SHARE
TWEET

Remote run commands (on laptop) script (receiver)

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