SHARE
TWEET

Remote run commands (on laptop) script (receiver)

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