I have a script where I've implemented switches using getopts. However, I'm having trouble referencing the next argument.
My script is for backporting a backup of our website on a local development environment. I've added a
-p switch to run some post-deploy steps. Here's my syntax:
backport -p /path/to/website_backup.sql.gz
So, before the switch, I was testing that a file was specified, and that it's a proper file. Since a filename path was the only argument, I could assume that it was necessary, and also that it would be the first argument (
if [[ $# -eq 0 ]] ; then echo 'Specifcy the sql file to backport.'; exit 0; fi if [[ ! -f "$1" ]]; then echo "$1 is not a valid file."; exit 0; fi
I found this answer which demonstrated an example of how to use getopts to parse switch arguments:
while getopts "p" opt; do case $opt in p) p_post_deploy=true ;; # Handle -a esac done
Of course, using
$1 as the argument didn't work after implementing getopts. Without the switch it was fine. But, when I added the switch, it was, of course, the first argument, which my script was testing for being a file.
$ backport -p /path/to/website_backup.sql.gz -p is not a valid file.
So, with the introduction of switches, I can't rely on any argument appearing at particular position in the command. Hard-coding
$2 won't work, because the filename argument won't be the second argument if there is no switch. I want a solution that will allow me to accept arguments after switches, and allow me to introduce new switches in the future while only updating the code to handle the new switches themselves (and not have to re-shuffle later arguments that may be moved after the introduction of a new switch).
I looked at the answers to the unix.stackexchange question that instructed me how to use getopts to parse switches. One of the answers mentioned
$* as a variable representing the remaining arguments.
if [[ "$*" -eq 0 ]] ; then echo 'Specifcy the sql file to backport.'; exit 0; fi
However, when I try to use it, I'm not expressing syntax correctly, and I get a parse error.
~/scripts/backport: line 14: [[: /d/Downloads/database.sql.gz: syntax error: operand expected (error token is "/d/Downloads/database.sql.gz")
How do I test the filename argument after getops?
Here is the script in its current version:
$ cat backport #!/bin/bash set -e while getopts "p" opt; do case $opt in p) p_post_deploy=true ;; esac done shift $(($OPTIND - 1)) # testing what this variable looks like printf "Remaining arguments are: %s\n" "$*" if [[ "$*" -eq 0 ]] ; then echo 'Specifcy the sql file to backport.'; exit 0; fi if [[ ! -f "$*" ]]; then echo "$* is not a valid file."; exit 0; fi drush @local.dev sql-drop -y ; zcat $1 | drush @local.dev sqlc ; drush @local.dev cr; if [ ! -z "$p_post_deploy" ] ; then echo "Running post-deploy..." SCRIPT_PATH=$(dirname "$BASH_SOURCE") source "$SCRIPT_PATH/post-deploy" post_deploy fi