Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # This script runs the list of commands and echoes output to a file
- # as well as a short log describing the command and exit status.
- # List open file descriptors:
- # ls -la /proc/$$/fd
- script_bn=$(basename "$0")
- script_fn=$(readlink -f "$0")
- script_ppid="$$"
- dir1='/home/buddha'
- dir2="${dir1}/run"
- dir3="${dir2}/old"
- bn='run_commands'
- switch_f="${dir2}/${bn}_switch.txt"
- txt1="${dir2}/${bn}.log"
- txt2="${dir2}/${bn}_stdout.log"
- txt3="${dir2}/${bn}_list.txt"
- exit_status=0
- # If the script isn't run with sudo / root privileges, then ask the user
- # to type his / her password, so we can run the script with full root
- # privileges. 'exec' is used in conjunction with 'sudo bash', thereby
- # replacing the current shell, and current instance of the script, with
- # the new one that has full privileges.
- if [[ $EUID -ne 0 ]]; then
- exec sudo bash -c "$0"
- fi
- # Clears the screen.
- clear
- # Creates a variable called 'regex', which contains a regex that will
- # be used to check if an array element / string is truly empty.
- regex='^[[:space:]]*$'
- # Stops the login manager.
- service lightdm stop
- killall -9 xiccd
- # Sets the TTY to blank the screen after 1 minute of inactivity.
- # Turns off powersave features of the TTY.
- setterm --blank 1 --powersave off --powerdown 0
- # Creates a function called 'get_tty', which will figure out what TTY
- # the script is currently running on. If the current instance of the
- # script doesn't know, then get that information from the previous
- # instance of the script (the first argument given to the script when
- # reloading using 'exec').
- get_tty () {
- tty_tmp=$(tty)
- if [[ ! $tty_tmp =~ ^/dev/tty[0-9]+ ]]; then
- tty_tmp="$1"
- fi
- echo "$tty_tmp"
- }
- c_tty=$(get_tty "$1")
- # Creates the output directory, as well as the text / log files
- # (if they don't already exist).
- mkdir -p "$dir3"
- echo 0 > "$switch_f"
- touch "$txt1" "$txt2" "$txt3"
- sync
- # Changes permission recursively for $dir2, so that my main PC
- # will be able to read and write to those files over the network.
- chown -R buddha "$dir2"
- chmod -R ugo+rw "$dir2"
- # trap ctrl-c and call ctrl_c()
- trap ctrl_c INT
- ctrl_c () {
- restore
- kill_children
- echo '** Trapped CTRL-C'
- exit
- }
- # Creates a function called 'flush', which will flush the cache
- # (free pagecache, dentries and inodes).
- flush () {
- while [[ 1 ]]; do
- sleep 30m
- echo 3 > /proc/sys/vm/drop_caches
- done
- }
- flush &
- # Creates a function called 'restore', which will restore STDOUT and
- # STDERR, as well as close file descriptor 3.
- restore () {
- sync
- exec &>"$c_tty"
- exec 3>&-
- }
- # Creates a function called 'kill_children', which will kill all child
- # processes to this script.
- kill_children () {
- mapfile -t child < <(ps -C "$script_bn" -o pid= | sort -rn)
- for (( i = 0; i < ${#child[@]}; i++ )); do
- if [[ ! ${child[${i}]} =~ $regex ]]; then
- child_pid=$(tr -d '[:blank:]' <<<"${child[${i}]}")
- if [[ $i -ne $script_ppid ]]; then
- echo "SIGTERM: ${script_bn} (${child_pid})"
- kill -s 15 "$child_pid"
- fi
- fi
- done
- }
- # Creates the 'switch' function, which will change $switch_f to '1'
- # if it's '0', or '0' if it's '1'.
- switch () {
- switch=$(cat "$switch_f")
- if [[ $switch -eq 0 ]]; then
- echo '1' > "$switch_f"
- elif [[ $switch -eq 1 ]]; then
- echo '0' > "$switch_f"
- fi
- }
- # Creates a function called 'init_log', to initiate the $count variable,
- # which will be used to rotate the STDOUT log, once it exceeds
- # 10000 lines. The function looks to see if there are any old log files
- # and bases $count on the previous last log file.
- init_log () {
- count=0
- declare old_log_tmp
- mapfile -t old_log < <(ls -1 "$dir3")
- if [[ ! ${old_log[0]} =~ $regex ]]; then
- for (( i = 0; i < ${#old_log[@]}; i++ )); do
- if [[ ! ${old_log[${i}]} =~ $regex ]]; then
- mapfile -d'.' -t line <<<"${old_log[${i}]}"
- el=$(( ${#line[@]} - 1 ))
- old_log_tmp+="${line[${el}]}\n"
- fi
- done
- count=$(echo -e "$old_log_tmp" | sort -rn | head -n 1)
- fi
- echo "$count"
- }
- # Creates a function called 'rotate_log', which will rotate $txt2 if
- # it exceeds 10000 lines.
- rotate_log () {
- lines=$(cat "$txt2" | wc -l)
- if [[ $lines -ge 10000 ]]; then
- let count++
- new="${txt2}.${count}"
- # ls -la /proc/$$/fd
- cp -p "$txt2" "$new"
- mv "$new" "$dir3"
- truncate --size=0 "$txt2"
- fi
- echo "$count"
- }
- # Creates a function called 'pid_running', which waits until the last
- # executed command has finished.
- pid_running () {
- pid="$!"
- # is=$(kill -0 $pid 2>&-)
- # while [[ $is ]]; do
- # sleep 1
- # pid=$(kill -0 $pid 2>&-)
- # done
- wait $pid
- exit_status="$?"
- }
- # Creates a function called 'reload', which reloads this script when
- # called.
- reload () {
- echo '** Reloading script...'
- write_list
- mapfile -t s_pid < <(pgrep "$script_bn")
- echo "tty: $c_tty"
- echo "script: $script_fn"
- echo "pid: ${s_pid[@]}"
- restore
- kill_children
- # switch
- exec "$script_fn" "$c_tty"
- }
- # Creates a function called 'run_cmd', which will run all commands in
- # $txt3.
- run_cmd () {
- mapfile -t functions < <(declare -F | grep -v '^declare -fx' | sed 's/^declare -f //')
- case ${run[0]} in
- 'cd')
- eval "${run[@]}"
- ;;
- *)
- for func in "{functions[@]}"; do
- if [[ ${run[0]} == "$func" ]]; then
- eval "${run[@]}"
- return
- fi
- done
- eval "${run[@]}" &
- pid_running
- ;;
- esac
- }
- # Creates a function called 'rw_log', which opens file descriptors to
- # append to the log files.
- # Specifically:
- # * Redirect both STDOUT and STDERR to $txt2
- # * Opens file descriptor 3 as output to $txt1
- rw_log () {
- exec &>>"$txt2"
- exec 3>>"$txt1"
- }
- # Creates a function called 'clear_log', which clears the log files
- # if called.
- clear_log () {
- truncate --size=0 "$txt2" "$txt1"
- }
- # Creates a function called 'upgrade', which will do a complete system
- # upgrade (install all available updates).
- upgrade () {
- apt-get update &
- pid_running
- apt-get --yes dist-upgrade &
- pid_running
- apt-get --yes autoclean &
- pid_running
- apt-get --yes autoremove &
- pid_running
- }
- irssi () {
- openvt -c 9 -f -- runuser buddha -c 'irssi -c EFNet'
- }
- # Creates a function called 'write_list', which overwrites the command
- # list, discarding the first line.
- write_list () {
- truncate --size=0 "$txt3"
- for (( i = 1; i < ${#list[@]}; i++ )); do
- echo -n "${list[${i}]}" >> "$txt3"
- done
- sync
- }
- rw_log
- count=$(init_log)
- while [[ 1 ]]; do
- mapfile -t list < <(cat "$txt3" 2>&-)
- mapfile -d' ' -t run <<<"${list[0]}"
- if [[ ${run[0]} =~ $regex ]]; then
- continue
- fi
- # Sender script needs to wait...
- switch
- count=$(rotate_log)
- date=$(date "+%F %H:%M:%S")
- echo
- run_cmd
- echo >&3
- echo "$date" >&3
- echo 'COMMAND:' >&3
- echo "${run[@]}" >&3
- echo "EXIT STATUS: $exit_status" >&3
- write_list
- # Now sender script can continue...
- switch
- done
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement