kill_chrome.sh 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/usr/bin/env bash
  2. # Kill zombie Chrome/Chromium processes listening on 127.0.0.1
  3. # Works cross-platform on macOS and Linux
  4. #
  5. # Usage:
  6. # ./bin/kill_chrome.sh # Kill Chrome processes with verification
  7. # ./bin/kill_chrome.sh --pkill # Quick kill using pkill (less precise)
  8. # ./bin/kill_chrome.sh --help # Show this help
  9. set -e
  10. # Detect OS
  11. OS="$(uname -s)"
  12. # Chrome binary patterns to search for (cross-platform)
  13. CHROME_PATTERNS=(
  14. "Google Chrome"
  15. "google-chrome"
  16. "chrome"
  17. "chromium"
  18. "chromium-browser"
  19. "Chromium"
  20. )
  21. # Function to kill Chrome processes
  22. kill_chrome_processes() {
  23. echo "Searching for Chrome processes listening on 127.0.0.1..."
  24. local killed=0
  25. for pattern in "${CHROME_PATTERNS[@]}"; do
  26. # Find processes matching the pattern with remote debugging
  27. if [ "$OS" = "Darwin" ]; then
  28. # macOS
  29. pids=$(ps aux | grep -i "$pattern" | grep -E "(remote-debugging-port|remote-debugging-address=127\.0\.0\.1)" | grep -v grep | awk '{print $2}' || true)
  30. else
  31. # Linux
  32. pids=$(ps aux | grep -i "$pattern" | grep -E "(remote-debugging-port|remote-debugging-address=127\.0\.0\.1)" | grep -v grep | awk '{print $2}' || true)
  33. fi
  34. if [ -n "$pids" ]; then
  35. echo "Found Chrome processes ($pattern): $pids"
  36. for pid in $pids; do
  37. # Try regular kill first
  38. if kill "$pid" 2>/dev/null; then
  39. echo " Killed $pid"
  40. killed=$((killed + 1))
  41. sleep 0.1
  42. fi
  43. # Check if still alive
  44. if ps -p "$pid" > /dev/null 2>&1; then
  45. # Check process state first to avoid attempting impossible kills
  46. if [ "$OS" = "Darwin" ]; then
  47. state=$(ps -o state -p "$pid" 2>/dev/null | tail -1 | tr -d ' ')
  48. else
  49. state=$(ps -o stat -p "$pid" 2>/dev/null | tail -1 | tr -d ' ')
  50. fi
  51. # Check if it's a zombie/uninterruptible process BEFORE trying to kill
  52. if [[ "$state" == *"Z"* ]] || [[ "$state" == *"D"* ]] || [[ "$state" == *"UNE"* ]]; then
  53. echo " WARNING: $pid is in uninterruptible/zombie state ($state) - cannot be killed"
  54. echo " Process will clean up automatically or requires system reboot"
  55. else
  56. # Try force kill
  57. echo " Force killing $pid with -9..."
  58. if kill -9 "$pid" 2>/dev/null; then
  59. # Wait briefly and verify
  60. sleep 0.2
  61. if ! ps -p "$pid" > /dev/null 2>&1; then
  62. echo " Force killed $pid"
  63. killed=$((killed + 1))
  64. else
  65. echo " WARNING: $pid survived kill -9 (state: $state)"
  66. fi
  67. else
  68. echo " ERROR: Failed to kill $pid (state: $state)"
  69. fi
  70. fi
  71. fi
  72. done
  73. fi
  74. done
  75. if [ $killed -eq 0 ]; then
  76. echo "No Chrome processes listening on 127.0.0.1 found (or all are zombie/uninterruptible)"
  77. else
  78. echo "Successfully killed $killed Chrome process(es)"
  79. fi
  80. # Show remaining Chrome processes (if any)
  81. echo ""
  82. echo "Remaining Chrome processes listening on 127.0.0.1:"
  83. for pattern in "${CHROME_PATTERNS[@]}"; do
  84. ps aux | grep -i "$pattern" | grep -E "(remote-debugging-port|remote-debugging-address=127\.0\.0\.1)" | grep -v grep || true
  85. done | head -10
  86. if [ $(ps aux | grep -iE "(google chrome|chrome|chromium)" | grep -E "(remote-debugging-port|remote-debugging-address=127\.0\.0\.1)" | grep -v grep | wc -l) -eq 0 ]; then
  87. echo " (none)"
  88. fi
  89. }
  90. # Alternative approach using pkill (faster but less precise)
  91. kill_chrome_pkill() {
  92. echo "Using pkill to kill all Chrome processes..."
  93. for pattern in "${CHROME_PATTERNS[@]}"; do
  94. if pkill -9 -f "$pattern" 2>/dev/null; then
  95. echo " Killed processes matching: $pattern"
  96. fi
  97. done
  98. sleep 0.5
  99. echo "Done"
  100. }
  101. # Show help
  102. show_help() {
  103. cat << EOF
  104. Kill zombie Chrome/Chromium processes listening on 127.0.0.1
  105. Usage:
  106. $0 [OPTIONS]
  107. Options:
  108. (none) Kill Chrome processes with state verification (recommended)
  109. --pkill, -p Quick kill using pkill (faster but less precise)
  110. --help, -h Show this help message
  111. Description:
  112. This script finds and kills Chrome/Chromium processes that are listening
  113. on 127.0.0.1 (with --remote-debugging-port or --remote-debugging-address).
  114. Supports multiple Chrome binary names:
  115. - Google Chrome / chrome / google-chrome
  116. - Chromium / chromium / chromium-browser
  117. Works on macOS and Linux.
  118. Zombie/uninterruptible processes (state UNE/Z/D) will be detected and
  119. reported but cannot be killed. They will clean up automatically.
  120. Examples:
  121. $0 # Kill with verification
  122. $0 --pkill # Quick kill all Chrome processes
  123. EOF
  124. }
  125. # Parse arguments
  126. if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
  127. show_help
  128. elif [ "$1" = "--pkill" ] || [ "$1" = "-p" ]; then
  129. kill_chrome_pkill
  130. else
  131. kill_chrome_processes
  132. fi