fant0men

runnet_receiver.sh

Nov 1st, 2019 (edited)
203
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. # This script runs the list of commands and echoes output to a file
  3. # as well as a short log describing the command and exit status.
  4. # List open file descriptors:
  5. # ls -la /proc/$$/fd
  6.  
  7. script_bn=$(basename "$0")
  8. script_fn=$(readlink -f "$0")
  9. script_ppid="$$"
  10. dir1='/home/buddha'
  11. dir2="${dir1}/run"
  12. dir3="${dir2}/old"
  13. bn='run_commands'
  14. switch_f="${dir2}/${bn}_switch.txt"
  15. txt1="${dir2}/${bn}.log"
  16. txt2="${dir2}/${bn}_stdout.log"
  17. txt3="${dir2}/${bn}_list.txt"
  18.  
  19. exit_status=0
  20.  
  21. # If the script isn't run with sudo / root privileges, then ask the user to type
  22. # his / her password, so we can run the script with full root privileges.
  23. # 'exec' is used in conjunction with 'sudo bash', thereby replacing the current
  24. # shell, and current instance of the script, with the new one that has full
  25. # privileges.
  26. if [[ $(whoami) != root ]]; then
  27.     exec sudo bash -c "$0"
  28. fi
  29.  
  30. # Clears the screen.
  31. clear
  32.  
  33. # Creates a variable called 'regex', which contains a regex that will
  34. # be used to check if an array element / string is truly empty.
  35. regex='^[[:space:]]*$'
  36.  
  37. # Stops the login manager.
  38. service lightdm stop
  39. killall -9 xiccd
  40.  
  41. # Sets the TTY to blank the screen after 1 minute of inactivity.
  42. # Turns off powersave features of the TTY.
  43. setterm --blank 1 --powersave off --powerdown 0
  44.  
  45. # Creates a function called 'get_tty', which will figure out what TTY
  46. # the script is currently running on. If the current instance of the
  47. # script doesn't know, then get that information from the previous
  48. # instance of the script (the first argument given to the script when
  49. # reloading using 'exec').
  50. get_tty () {
  51.     tty_tmp=$(tty)
  52.  
  53.     if [[ ! $tty_tmp =~ ^/dev/tty[0-9]+ ]]; then
  54.         tty_tmp="$1"
  55.     fi
  56.  
  57.     echo "$tty_tmp"
  58. }
  59.  
  60. c_tty=$(get_tty "$1")
  61.  
  62. # Creates the output directory, as well as the text / log files
  63. # (if they don't already exist).
  64. mkdir -p "$dir3"
  65.  
  66. echo 0 > "$switch_f"
  67.  
  68. touch "$txt1" "$txt2" "$txt3"
  69.  
  70. sync
  71.  
  72. # Changes permission recursively for $dir2, so that my main PC
  73. # will be able to read and write to those files over the network.
  74. chown -R buddha "$dir2"
  75. chmod -R ugo+rw "$dir2"
  76.  
  77. # trap ctrl-c and call ctrl_c()
  78. trap ctrl_c INT
  79.  
  80. ctrl_c () {
  81.     restore
  82.     kill_children
  83.     echo '** Trapped CTRL-C'
  84.     exit
  85. }
  86.  
  87. # Creates a function called 'flush', which will flush the cache
  88. # (free pagecache, dentries and inodes).
  89. flush () {
  90.     while true; do
  91.         sleep 30m
  92.         echo 3 > /proc/sys/vm/drop_caches
  93.     done
  94. }
  95.  
  96. flush &
  97.  
  98. # Creates a function called 'restore', which will restore STDOUT and
  99. # STDERR, as well as close file descriptor 3.
  100. restore () {
  101.     sync
  102.     exec &>"$c_tty"
  103.     exec 3>&-
  104. }
  105.  
  106. # Creates a function called 'kill_children', which will kill all child
  107. # processes to this script.
  108. kill_children () {
  109.     mapfile -t child < <(ps -C "$script_bn" -o pid | tail -n +2 | sort -rn)
  110.  
  111.     for (( i = 0; i < ${#child[@]}; i++ )); do
  112.         if [[ ! ${child[${i}]} =~ $regex ]]; then
  113.             child_pid=$(tr -d '[:blank:]' <<<"${child[${i}]}")
  114.  
  115.             if [[ $i -ne $script_ppid ]]; then
  116.                 echo "SIGTERM: ${script_bn} (${child_pid})"
  117.                 kill -s 15 "$child_pid"
  118.             fi
  119.         fi
  120.     done
  121. }
  122.  
  123. # Creates the 'switch' function, which will change $switch_f to '1'
  124. # if it's '0', or '0' if it's '1'.
  125. switch () {
  126.     switch=$(cat "$switch_f")
  127.  
  128.     if [[ $switch -eq 0 ]]; then
  129.         echo '1' > "$switch_f"
  130.     elif [[ $switch -eq 1 ]]; then
  131.         echo '0' > "$switch_f"
  132.     fi
  133. }
  134.  
  135. # Creates a function called 'init_log', to initiate the $count variable,
  136. # which will be used to rotate the STDOUT log, once it exceeds
  137. # 10000 lines. The function looks to see if there are any old log files
  138. # and bases $count on the previous last log file.
  139. init_log () {
  140.     count=0
  141.     declare old_log_tmp
  142.  
  143.     mapfile -t old_log < <(ls -1 "$dir3")
  144.  
  145.     if [[ ! ${old_log[0]} =~ $regex ]]; then
  146.         for (( i = 0; i < ${#old_log[@]}; i++ )); do
  147.             if [[ ! ${old_log[${i}]} =~ $regex ]]; then
  148.                 mapfile -d'.' -t line <<<"${old_log[${i}]}"
  149.                 el=$(( ${#line[@]} - 1 ))
  150.                 old_log_tmp+="${line[${el}]}\n"
  151.             fi
  152.         done
  153.  
  154.         count=$(echo -e "$old_log_tmp" | sort -rn | head -n 1)
  155.  
  156.     fi
  157.  
  158.     echo "$count"
  159. }
  160.  
  161. # Creates a function called 'rotate_log', which will rotate $txt2 if
  162. # it exceeds 10000 lines.
  163. rotate_log () {
  164.     lines=$(cat "$txt2" | wc -l)
  165.  
  166.     if [[ $lines -ge 10000 ]]; then
  167.         let count++
  168.  
  169.         new="${txt2}.${count}"
  170.  
  171.         #ls -la /proc/$$/fd
  172.  
  173.         cp "$txt2" "$new"
  174.         mv "$new" "$dir3"
  175.  
  176.         truncate --size=0 "$txt2"
  177.     fi
  178.  
  179.     echo "$count"
  180. }
  181.  
  182. # Creates a function called 'pid_running', which waits until the last
  183. # executed command has finished.
  184. pid_running () {
  185.     pid="$!"
  186.  
  187.     #is=$(kill -0 $pid 2>&-)
  188.  
  189.     #while [[ $is ]]; do
  190.     #   sleep 1
  191.     #   pid=$(kill -0 $pid 2>&-)
  192.     #done
  193.  
  194.     wait $pid
  195.  
  196.     exit_status="$?"
  197. }
  198.  
  199. # Creates a function called 'reload', which reloads this script when
  200. # called.
  201. reload () {
  202.     echo '** Reloading script...'
  203.  
  204.     write_list
  205.  
  206.     mapfile -t s_pid < <(pgrep "$script_bn")
  207.  
  208.     echo "tty: $c_tty"
  209.     echo "script: $script_fn"
  210.     echo "pid: ${s_pid[@]}"
  211.  
  212.     restore
  213.     kill_children
  214.     #switch
  215.     exec "$script_fn" "$c_tty"
  216. }
  217.  
  218. # Creates a function called 'run_cmd', which will run all commands in
  219. # $txt3.
  220. run_cmd () {
  221.     mapfile -t functions < <(declare -F | grep -v '^declare -fx' | sed 's/^declare -f //')
  222.  
  223.     case ${run[0]} in
  224.         'cd')
  225.             eval "${run[@]}"
  226.         ;;
  227.         *)
  228.             for func in "{functions[@]}"; do
  229.                 if [[ ${run[0]} == $func ]]; then
  230.                     eval "${run[@]}"
  231.                     return
  232.                 fi
  233.             done
  234.  
  235.             eval "${run[@]}" &
  236.  
  237.             pid_running
  238.         ;;
  239.     esac
  240. }
  241.  
  242. # Creates a function called 'rw_log', which opens file descriptors to
  243. # append to the log files.
  244. # Specifically:
  245. # * Redirect both STDOUT and STDERR to $txt2
  246. # * Opens file descriptor 3 as output to $txt1
  247. rw_log () {
  248.     exec &>>"$txt2"
  249.     exec 3>>"$txt1"
  250. }
  251.  
  252. # Creates a function called 'clear_log', which clears the log files
  253. # if called.
  254. clear_log () {
  255.     truncate --size=0 "$txt2" "$txt1"
  256. }
  257.  
  258. # Creates a function called 'upgrade', which will do a complete system
  259. # upgrade (install all available updates).
  260. upgrade () {
  261.     apt-get update &
  262.     pid_running
  263.     apt-get --yes dist-upgrade &
  264.     pid_running
  265.     apt-get --yes autoclean &
  266.     pid_running
  267.     apt-get --yes autoremove &
  268.     pid_running
  269. }
  270.  
  271. irssi () {
  272.     openvt -c 9 -f -- runuser buddha -c 'irssi -c EFNet'
  273. }
  274.  
  275. # Creates a function called 'write_list', which overwrites the command
  276. # list, discarding the first line.
  277. write_list () {
  278.     truncate --size=0 "$txt3"
  279.  
  280.     for (( i = 1; i < ${#list[@]}; i++ )); do
  281.  
  282.         echo -n "${list[${i}]}" >> "$txt3"
  283.     done
  284.  
  285.     sync
  286. }
  287.  
  288. rw_log
  289. count=$(init_log)
  290.  
  291. while true; do
  292.     mapfile -t list < <(cat "$txt3" 2>&-)
  293.  
  294.     mapfile -d' ' -t run <<<"${list[0]}"
  295.  
  296.     if [[ ${run[0]} =~ $regex ]]; then
  297.         continue
  298.     fi
  299.  
  300.     # Sender script needs to wait...
  301.     switch
  302.  
  303.     count=$(rotate_log)
  304.  
  305.     date=$(date "+%F %H:%M:%S")
  306.  
  307.     echo
  308.  
  309.     run_cmd
  310.  
  311.     echo >&3
  312.     echo "$date" >&3
  313.     echo 'COMMAND:' >&3
  314.     echo "${run[@]}" >&3
  315.     echo "EXIT STATUS: $exit_status" >&3
  316.  
  317.     write_list
  318.  
  319.     # Now sender script can continue...
  320.     switch
  321. done
  322.  
RAW Paste Data