0

I made a script to restart my web server automatically, do certain checks, and then print a message with the time stamp to a log file. Since I call this file from different places (cron jobs, when I update my site, manually, etc.), I wanted to have a way to print different messages to the log file based on the reason why I'm calling it. I decided to use options to do this, and I also decided to add help, verbose, and test options as well.

Code for the options part:

# initializing variables
test=false
help=false
verbose=false
modeCount=0
msg="restarted"

# looking at options
while getopts ":aeghmstv" option; do
    case $option in
        a) # Automatic restart
            ((modeCount+=1))
            msg="$msg automatically";;
        e) # Error-triggered restart
            ((modeCount+=1))
            msg="$msg due to an error";;
        g) # Pull-triggered restart
            ((modeCount+=1))
            msg="$msg on git pull";;
        h) # Help
            help=true;;
        m) # Manual restart
            ((modeCount+=1))
            msg="$msg manually";;
        s) # Startup-triggered restart
            ((modeCount+=1))
            msg="$msg on startup";;
        t) # Testing mode
            test=true;;
        v) # Verbose mode
            verbose=true;;
       \?) # Invalid option
            echo "Error: Invalid option; use the h option for help"
            exit;;
    esac
done

# checking for input errors
if [ "$help" == true ]; then
    if [ $modeCount -gt 0 ] || [ "$test" == true ] || [ "$verbose" == true ]; then
        echo "Error: No other options can be used with h; use the h option for help"
    else
        help
    fi
    exit
fi
if [ $modeCount != 1 ]; then
    echo "Error: 1 log message option must be used; use the h option for help"
    exit
fi

But, additionally, I want to be able to pass a string as a positional parameter to add additional information to my log file. For example, if I run:

./restart.sh -a

It logs something like:

2021-10-04T00:00:04 restarted automatically

But I want to be able to change that so that I could (optionally) run:

./restart.sh -a "daily restart"

And it would instead log:

2021-10-04T00:00:04 restarted automatically: daily restart

I found this question about mixing getops and parameters, but I do not know how I would do this if I want the parameters to be optional.

Once I get that string, it will be very easy to simply add a line like:

msg="$msg: $info"

But I am not sure how I would verify that such a parameter exists and then subsequently store it in a variable.

PS: I would also like it to work no matter what order the parameters/options are in. For example, I want:

./restart.sh -a "daily restart"

and

./restart.sh "daily restart" -a

to work the same way.

miken32
  • 42,008
  • 16
  • 111
  • 154
  • 1
    After `getopts` is done, the positional parameters are all the non-option arguments after them. – Barmar Oct 05 '21 at 20:27

1 Answers1

-1

You can write your own if/else to parse second parameter. It will solve your issue, but I do not recommend this way. Anyway, kindly try:

#!/bin/bash

while getopts ":aeghmstv" option; do case $option in a) # Automatic restart ((modeCount+=1)) if [ ! "${2:0:1}" == "-" ]; then msg="$2" shift else msg=" automatically" fi;; esac echo "msg: $msg" done

Saboteur
  • 1,331
  • 5
  • 12
  • I thought about using $OPTARG, but since I have 5 different options (a, e, g, m, s) that I want to make be able to use additional parameter, I would have to add an additional 5 options (which seems like too much for me). I was specifically wondering if there was some way to consume 1 optional parameter separate from the options. Like how they did it in the linked question, except that the parameter is optional. I also want it to be order-agnostic, and this requires a pretty specific order for everything. – Riggs Markham Oct 05 '21 at 22:28
  • In this case you can use your own loop with parsing arguments and try to parse additional parameter if it starts with dash. – Saboteur Oct 06 '21 at 07:51
  • I have updated my answer with example of manual checking for next argument. Kindly try if it fit for you – Saboteur Oct 06 '21 at 07:59