#!/bin/bash -e
#For course FYD500, exam 2018
#No warranty provided

# A script that provides user with some simple actions,
#    chosen either from argument or in menu if none are included

#BUGS
# 1. One trap is not fully functioning see TODO further down.

#Options if no terminal argument is given
OPTIONS=\
"(h)elp
(p)rocesses
(u)sers
(d)ownload
(f)iles
(q)uit"



### Supported functionality ###

function help {
    echo -e "\\033[1m${0}\\033[0m usage:
    \\e[0;31m-h\\e[0m             Prints this help
    \\e[0;31m-p\\e[0m             Show total number of processes and list the 10 most not nice ones
    \\e[0;31m-u \\e[0m            Show all local users and their login shell with less
    \\e[0;31m-d\\e[0m             Asks for path and downloads Stallman's frontpage to given path
                                   (defaults to /tmp/ if no path given)
    \\e[0;31m-f\\e[0m             Asks for directory and returns total disk space used by it in MB (recursively)

    If the arguments '-q' or '-h' is given no additional commands will be executed,
        otherwise multiple arguments can be given to this program and executed in order.
    However, if no arguments are given at launch, the user is presented with choices inside of the program.
        In this menu the user can choose between these options by entering the integer (1-6)
    "

}

function processes {
    #Number of processes (excludes the title row)
    let PROCS=$(ps -eo pid,cmd,ni --sort=-ni | wc -l)-1
    echo "Number of processes: $PROCS"; echo

    #show 10 lowest NIce processes
    echo "Most NOT nice processes: "
    ps -eo pid,cmd,ni --sort=-ni | tail -n 10
    echo
}

function users {
    awk -F: '{ print "User: " $1 "\nShell: " $7 "\n"}' < /etc/passwd | less
}

function download {
    FILE_NAME="stallman.html"

    echo "In what directory do you wish to save this file? (either absolute or relative path)"
    read MY_PATH

    while [ ! -d "$MY_PATH" ]
    do
        if [ -z "$MY_PATH" ]; then
            echo "No path given, defaulting to /tmp/"
            MY_PATH="/tmp/"
            break
        fi
        echo -e "The folder '${MY_PATH}' does not exist!\n"
        echo "In what directory do you wish to save this file? (either absolute or relative path)"
        read MY_PATH
    done

    wget https://stallman.org/ -O "${MY_PATH}/${FILE_NAME}"
}

function files {
    echo "Enter the directory (absolute or relative path) which you'd like to know the size of"
    read MY_PATH
    #MY_PATH=$(pwd)

    UNIT="MB"
    let UNIT_RAW=1024*1024

    SIZE=$(df -B $UNIT_RAW "$MY_PATH" | awk 'FNR==2 {print $2}')

    # Unexpected output (awk parsing return empty string)
    if [ -z "$SIZE" ]; then
        return 1
    fi

    echo "Disk space used by $MY_PATH is $SIZE $UNIT"
}



### Helper functions ###

function ask_quit {
    echo "Would you like to quit? (y/n)"
    read PROMPT

    if [ "$PROMPT" = "y" ]; then
        echo "OK exiting..."
        exit 0
    fi

    return
}

#send all arguments here to see if they are valid (with "$@")
#if either help or any invalid options are given it will not continue with other commands
function arguments_valid {
    while [ $# -gt 0 ]
    do
        case $1 in
            "-h")
                help
                exit 0
                ;;
            "-p")
                ;;
            "-u")
                ;;
            "-d")
                ;;
            "-f")
                ;;
            *)
                echo "Invalid detected. Bye!"
                exit 1
                ;;
        esac
        shift
    done
}

function menu {

    #present exit dialogue on SIGINT if already in menu
    trap ask_quit SIGINT

    echo -e "\tNo arguments were given, choose between the options below by entering the integer (1-6)\n"

    select OPTION in ${OPTIONS};
    do
        #TODO! The below trap seems to disable the 'ask_quit' trap above,
             # so it seems to be a problem with changing the trap like this multiple times.
             # ideally it should change back and forth depending on if we're in menu or in these functions below.
        #return to menu on SIGINT
        #trap menu SIGINT
        case $OPTION in
            "(h)elp")
                help
                ;;
            "(p)rocesses")
                processes
                ;;

            "(u)sers")
                users
                ;;

            "(d)ownload")
                download
                ;;

            "(f)iles")
                files
                ;;

            "(q)uit")
                echo "Bye!"
                break
                ;;
            *)
                echo "Invalid option. Bye!"
                break
                ;;

        esac
    done
}




### Option menu for user ###

#The program starts here!
echo -e "\e[1;35mWelcome to the exam script of 2018! Let's begin\e[0m\n"

#Hint:
#Can test traps with
#ps aux | grep exam2018_test.sh
#kill -QUIT pid
#kill -INT  pid

#Default behavior ask for confirmation to quit on these signals
trap ask_quit SIGQUIT SIGINT

#No options presents user with alternatives in terminal
if [ $# -eq 0 ]; then
    menu

#Arguments given to program
else
    arguments_valid "$@"

    while [ $# -gt 0 ]
    do
        case $1 in
            "-h")
                help
                exit 0
                ;;
            "-p")
                processes
                ;;
            "-u")
                users
                ;;
            "-d")
                download
                ;;
            "-f")
                files
                ;;
            *)
                echo "Invalid option. Bye!"
                exit 1
                ;;
        esac
        shift
    done
    exit 0
fi

Last modified | History | Source | Preferences