SHARE
TWEET

Kill Firefox (and Chrome) bash script

a guest Dec 3rd, 2019 104 in 26 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. # This script creates an infinite while loop, which checks the available
  3. # RAM every 1 second, and kills Firefox, Chrome, Chromium and
  4. # Tor Browser if less than 1 GB is available. The script will only kill
  5. # the tabs, but not the main window itself, so the application keeps
  6. # running but RAM is still freed up.
  7. #
  8. # The web browser is always the application that ends up using the most
  9. # RAM on my system. Once the RAM is nearly full, Linux starts swapping
  10. # and gradually slows down more and more, until grinding to a complete
  11. # halt when RAM is completely full. Then Linux calls the Out Of Memory
  12. # (OOM) manager to kill processes to free up RAM. It might kill a
  13. # critical process, a program that's been running for a very long time
  14. # (i.e. video encoding). To prevent that from happening, I created
  15. # this script.
  16.  
  17. # Creates a function called 'now', which will print the date and time.
  18. now () { date '+%F %H:%M:%S'; }
  19.  
  20. regex='^[[:space:]]*$'
  21.  
  22. # Creates a function called 'is_chromium', which checks if Chromium
  23. # or Chrome is running.
  24. is_chromium () {
  25.  
  26.     for comm in chrome chromium; do
  27.         pgrep "$comm" | tr -d '[:blank:]'
  28.     done
  29. }
  30.  
  31. # Creates a function called 'kill_chromium', which kills all child
  32. # processes belonging to either Chromium or Chrome.
  33. kill_chromium () {
  34.  
  35.     pid_switch=0
  36.  
  37.     for comm in chrome chromium; do
  38.  
  39.         mapfile -t parent < <(ps -C "$comm" -o ppid | tail -n +2 | tr -d '[:blank:]' | sort -u)
  40.         mapfile -t child < <(ps -C "$comm" -o pid | tail -n +2 | tr -d '[:blank:]')
  41.  
  42.         for (( i = 0; i < ${#child[@]}; i++ )); do
  43.             if [[ ! ${child[${i}]} =~ $regex ]]; then
  44.                 child_pid="${child[${i}]}"
  45.  
  46.                 for (( j = 0; j < ${#parent[@]}; j++ )); do
  47.                     if [[ ! ${parent[${j}]} =~ $regex ]]; then
  48.                         parent_pid="${parent[${j}]}"
  49.  
  50.                         if [[ $parent_pid == $child_pid ]]; then
  51.                             pid_switch=1
  52.                         fi
  53.                     fi
  54.                 done
  55.  
  56.                 if [[ $pid_switch -eq 0 ]]; then
  57.                     echo "SIGKILL: ${child_pid}"
  58.                     kill -9 "$child_pid"
  59.                 else
  60.                     pid_switch=0
  61.                 fi
  62.             fi
  63.         done
  64.     done
  65. }
  66.  
  67. # Creates a function called 'kill_firefox', which kills all child
  68. # processes belonging to either Firefox or Tor Browser.
  69. kill_firefox () {
  70.  
  71.     declare -a pids_tmp pids
  72.  
  73.     for name in 'Web Content' 'WebExtensions'; do
  74.         mapfile -t pids_tmp < <(pgrep -x "$name" | tr -d '[:blank:]')
  75.         pids+=( "${pids_tmp[@]}" )
  76.     done
  77.  
  78.     for name in firefox tor; do
  79.         for (( i = 0; i <= ${#pids[@]}; i++ )); do
  80.             if [[ ! ${pids[${i}]} =~ $regex ]]; then
  81.                 pid="${pids[${i}]}"
  82.                 p_name="$(ps -p "$pid" -o comm | tail -n +2)"
  83.                 if [[ $p_name == $name ]]; then
  84.                     unset -v pids[${i}]
  85.                 fi
  86.             fi
  87.         done
  88.     done
  89.  
  90.     kill -9 "${pids[@]}"
  91. }
  92.  
  93. # Creates a file name for the log.
  94. log_killed="${HOME}/firefox_chromium_killed.log"
  95.  
  96. # If $log_killed is not a file, create it.
  97. if [[ ! -f $log_killed ]]; then
  98.     touch "$log_killed"
  99. fi
  100.  
  101. # Creates an infinite while loop.
  102. while true; do
  103.  
  104.     # Sleeps for 1 second.
  105.     sleep 1
  106.  
  107.     # Unsets $free_ram, since this might not be the first time the loop
  108.     # is run.
  109.     unset -v free_ram
  110.  
  111.     # Runs 'free', stores output in the $free_ram array,
  112.     # and sets a couple of variables based on that output.
  113.     mapfile -t free_ram < <(free)
  114.     ram=$(echo "${free_ram[1]}" | sed 's/ \+/ /g' | cut -d' ' -f4)
  115.     swap=$(echo "${free_ram[2]}" | sed 's/ \+/ /g' | cut -d' ' -f4)
  116.     avail=$(echo "${free_ram[1]}" | sed 's/ \+/ /g' | cut -d' ' -f7)
  117.  
  118.     # Prints the free and available RAM and SWAP.
  119.     echo "FREE (kibibytes)"
  120.     echo "RAM: ${ram}, SWAP: ${swap}"
  121.     echo "***"
  122.     echo "AVAILABLE (kibibytes)"
  123.     echo -e "RAM: ${avail}\n"
  124.  
  125.     # If available RAM is less than 1GB...
  126.     if [[ $avail -lt 1000000 ]]; then
  127.  
  128.         # Checks if Firefox and Chromium are running.
  129.         # $is_chromium is an array, since the output probably spans
  130.         # across multiple lines, due to Chromium being highly
  131.         # multithreaded and keeping separate threads / processes
  132.         # for every window and tab.
  133.         is_firefox=$(pgrep -x firefox)
  134.         is_tor=$(pgrep -x tor)
  135.         mapfile -t is_chromium < <(is_chromium)
  136.  
  137.         # If Firefox is running, then kill it, print a message to the
  138.         # screen, and append a message to the log.
  139.         if [[ $is_firefox ]]; then
  140.  
  141.             time=$(now)
  142.  
  143.             echo -e "${time}: Killing Firefox...\n" | tee --append "$log_killed"
  144.             kill_firefox
  145.         fi
  146.  
  147.         # If Tor Browser is running, then kill it, print a message to
  148.         # the screen, and append a message to the log.
  149.         if [[ $is_tor ]]; then
  150.  
  151.             time=$(now)
  152.  
  153.             echo -e "${time}: Killing Tor Browser...\n" | tee --append "$log_killed"
  154.             kill_firefox
  155.         fi
  156.  
  157.         # If Chromium is running, then...
  158.         if [[ ! ${is_chromium[0]} =~ $regex ]]; then
  159.  
  160.             time=$(now)
  161.  
  162.             echo -e "${time}: Killing Chromium...\n" | tee --append "$log_killed"
  163.             kill_chromium
  164.         fi
  165.  
  166.         # Writes cached writes to disk. Hopefully this will also clear
  167.         # up a little RAM.
  168.         sync
  169.  
  170.     fi
  171.  
  172. done
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top