Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to conditionally add flags to shell scripts?

Tags:

bash

scripting

I want to run a command inside my bash script with or without a -v flag depending on if the environment variable $VERBOSE is defined. Something like this:

#!/bin/bash

/usr/local/bin/mongo-connector \
  -m $MONGO_HOST \
  -t $NEO_URI \
  [if $VERBOSE then -v ] \
  -stdout
like image 284
Dziamid Avatar asked Mar 23 '17 19:03

Dziamid


People also ask

What does != Mean in shell script?

And the != operator means 'is not equal to', so [ $? != 0 ] is checking to see if $? is not equal to zero. Putting all that together, the above code checks to see if the grep found a match or not.

What does [- Z $1 mean in bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script. Follow this answer to receive notifications.

What is $@ in bash script?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.


3 Answers

For readability, consider using an array to store the arguments.

args=(
  -m "$MONGO_HOST"
  -t "$NEO_URI"
  -stdout
)
if [[ -v VERBOSE ]]; then
    args+=(-v)
fi
/usr/local/bin/mongo-connector "${args[@]}"
like image 141
chepner Avatar answered Sep 30 '22 12:09

chepner


#!/bin/bash

/usr/local/bin/mongo-connector \
  -m "$MONGO_HOST" \
  -t "$NEO_URI" \
  ${VERBOSE:+-v} \
  -stdout

If VERBOSE is set and non-empty, then ${VERBOSE:+-v} evaluates to -v. If VERBOSE is unset or empty, it evaluates to the empty string. Note that this is an instance where you must avoid using double quotes. If you write: cmd "${VERBOSE:+-v}" rather than cmd ${VERBOSE+:v}, the behavior is semantically different when VERBOSE is empty or unset. In the former case, cmd is called with one argument (the empty string), while in the latter case cmd is called with zero arguments.

To test if VERBOSE is set to a particular string, you can do things like:

/usr/local/bin/mongo-connector \
  -m "$MONGO_HOST" \
  -t "$NEO_URI" \
  $(case ${VERBOSE} in (v1) printf -- '-v foo';; (v2) printf -- '-v bar';; esac )\
  -stdout

but it seems cleaner to write that as

case "${VERBOSE}" in
v1) varg=foo;;
v2) varg=bar;;
*)  unset varg;;
esac
/usr/local/bin/mongo-connector -m "$MONGO_HOST" -t "$NEO_URI" \
      ${varg+-v "$varg"} -stdout

Again, note the use of double quotes here. You want them around $varg to ensure that only one string is passed, and you do not want "${varg+-v "$varg"}" because you want to ensure that you do not pass an empty string. Also, since the case statement explicitly unsets varg, we can now omit the :.

like image 45
William Pursell Avatar answered Sep 30 '22 13:09

William Pursell


This seems to work:

composer dump-autoload $([ "$env" = "production" ] && printf '--classmap-authoritative')
like image 37
mpen Avatar answered Sep 30 '22 14:09

mpen