Bash: Setting default values for variables

I have a variable I want to use in bash script. The user will pass an argument
to the script and I will store it in `arg_fql`. If the user does not pass the variable,
I still never set arg_fql, but I set another variable to a default. However, if the user
passes a value, `arg_fql` will be set to what the user specified

I have used the following code.

[ -v arg_fql ] && fql="$arg_fql"
fql=${arg_fql:-"0.002 0.003 1 2"}

Would the following have the same effect?

fql=${arg_fql:-"0.002 0.003 1 2"}

You did not specify the behaviour, if the user passes an argument of length zero. The general convention is to treat this as a "non-existing argument", so I will assume this in my solution, but of course there might be applications where we have to treat these two cases differently.

Assuming that the user passes the optional parameter to your script in $1, you could write:

if [[ -z $1 ]]
then
  another_variable=default
else
  arg_fql=$1
fi

Whether they produce the same results or not depends on which version of bash you are using.

On versions of bash less than or equal to at least version 3.2.57(1), test -v variable , [ -v variable ] , and [[ -v variable ]] will give you an error because -r is not recognized as a valid operator.

In versions of bash where -r is recognized as an operator, the command sequence:

[ -v arg_fql ] && fql="$arg_fql"
fql=${arg_fql:-"0.002 0.003 1 2"}

will produce the same final results as the command sequence:

fql=${arg_fql:-"0.002 0.003 1 2"}

but the first sequence will a run little bit slower and consume a little bit more system resources than the second sequence.

Note also that the second sequence is required to work in any shell that tries to conform to the POSIX standard's requirements for parameter expansions (and is, therefore, portable across many shells) while the first sequence uses an extension to the standards and, as far as I know, only works with some versions of ksh and some versions of bash .

Note also that even on shells that recognize -v as an operator, the output produced by:

[ -v arg_fql ] && fql="$arg_fql" || fql="0.002 0.003 1 2"

is not equivalent to the output produced by:

fql=${arg_fql:-"0.002 0.003 1 2"}

in cases where arg_fql has been defined to be an empty string before running the above sequences. In this case, the first sequence will set fqi to an empty string while the second sequence will set it to the string 0.002 0.003 1 2 .