SHARE
TWEET

Remote run commands (on laptop) script (receiver)

a guest Dec 2nd, 2019 93 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.     restore
  72.     kill_children
  73.     echo '** Trapped CTRL-C'
  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.     mapfile -t s_pid < <(pgrep "$script_bn")
  215.  
  216.     echo "tty: $c_tty"
  217.     echo "script: $script_fn"
  218.     echo "pid: ${s_pid[@]}"
  219.  
  220.     restore
  221.     kill_children
  222.     exec "$script_fn" "$c_tty"
  223. }
  224.  
  225. # Creates a function called 'run_cmd', which will run all commands in
  226. # $txt3.
  227. run_cmd () {
  228.  
  229.     mapfile -t functions < <(declare -F | grep -v '^declare -fx' | sed 's/^declare -f //')
  230.  
  231.     case ${run[0]} in
  232.         'cd')
  233.  
  234.             eval "${run[@]}"
  235.         ;;
  236.         *)
  237.  
  238.             for func in "{functions[@]}"; do
  239.  
  240.                 if [[ ${run[0]} == $func ]]; then
  241.                     eval "${run[@]}"
  242.                     return
  243.                 fi
  244.             done
  245.  
  246.             eval "${run[@]}" &
  247.  
  248.             pid_running
  249.         ;;
  250.     esac
  251. }
  252.  
  253. if [[ $USER != root ]]; then
  254.  
  255.     echo -e "You must be root to run this script!\n"
  256.     exit
  257.  
  258. fi
  259.  
  260. # Creates a function called 'rw_log', which opens file descriptors to
  261. # append to the log files.
  262. # Specifically:
  263. # * Redirect both STDOUT and STDERR to $txt2
  264. # * Opens file descriptor 3 as output to $txt1
  265. rw_log () {
  266.  
  267.     exec &>>"$txt2"
  268.     exec 3>>"$txt1"
  269.  
  270. }
  271.  
  272. # Creates a function called 'clear_log', which clears the log files
  273. # if called.
  274. clear_log () {
  275.  
  276.     truncate --size=0 "$txt2" "$txt1"
  277. }
  278.  
  279. # Creates a function called 'upgrade', which will do a complete system
  280. # upgrade (install all available updates).
  281. upgrade () {
  282.     apt-get update &
  283.     pid_running
  284.     apt-get --yes dist-upgrade &
  285.     pid_running
  286.     apt-get --yes autoclean &
  287.     pid_running
  288.     apt-get --yes autoremove &
  289.     pid_running
  290. }
  291.  
  292. irssi () {
  293.     openvt -c 9 -f -- runuser buddha -c 'irssi -c EFNet'
  294. }
  295.  
  296. # Creates a function called 'write_list', which overwrites the command
  297. # list, discarding the first line.
  298. write_list () {
  299.  
  300.     truncate --size=0 "$txt3"
  301.  
  302.     for (( i = 1; i < ${#list[@]}; i++ )); do
  303.  
  304.         echo -n "${list[${i}]}" >> "$txt3"
  305.     done
  306.  
  307.     sync
  308. }
  309.  
  310. rw_log
  311. count=$(init_log)
  312.  
  313. while true; do
  314.  
  315.     mapfile -t list < <(cat "$txt3" 2>&-)
  316.  
  317.     mapfile -d' ' -t run <<<"${list[0]}"
  318.  
  319.     if [[ ${run[0]} =~ $regex ]]; then
  320.         continue
  321.     fi
  322.  
  323.     # Sender script needs to wait...
  324.     switch
  325.  
  326.     count=$(rotate_log)
  327.  
  328.     date=$(date "+%F %H:%M:%S")
  329.  
  330.     echo
  331.  
  332.     run_cmd
  333.  
  334.     echo >&3
  335.     echo "$date" >&3
  336.     echo 'COMMAND:' >&3
  337.     echo "${run[@]}" >&3
  338.     echo "EXIT STATUS: $exit_status" >&3
  339.  
  340.     write_list
  341.  
  342.     # Now sender script can continue...
  343.     switch
  344.  
  345. 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