It is pretty clear that with shell scripting this sort of thing can be accomplished in a huge number of ways (more than most programming languages) because of all the different
I see several questions here.
“Can I write something that actually reflects this logic”
Yes. There are a few ways you can do it. Here's one:
if [[ "$1" != "" ]]; then
DIR="$1"
else
DIR=.
fi
“What is the difference between this and DIR=${1-.}
?”
The syntax ${1-.}
expands to .
if $1
is unset, but expands like $1
if $1
is set—even if $1
is set to the empty string.
The syntax ${1:-.}
expands to .
if $1
is unset or is set to the empty string. It expands like $1
only if $1
is set to something other than the empty string.
“Why can't I do this? DIR="$1" || '.'
”
Because this is bash, not perl or ruby or some other language. (Pardon my snideness.)
In bash, ||
separates entire commands (technically it separates pipelines). It doesn't separate expressions.
So DIR="$1" || '.'
means “execute DIR="$1"
, and if that exits with a non-zero exit code, execute '.'
”.
How about this:
DIR=.
if [ $# -gt 0 ]; then
DIR=$1
fi
$#
is the number of arguments given to the script, and -gt
means "greater than", so you basically set DIR
to the default value, and if the user has specified an argument, then you set DIR
to that instead.
I use a simple helper function to make such assignments look cleaner. The function below accepts any number of arguments, but returns the first one that's not the empty string.
default_value() {
# Return the first non-empty argument
while [[ "$1" == "" ]] && [[ "$#" -gt "0" ]]; do
shift
done
echo $1
}
x=$(default_value "$1" 0)