Bash: How to set a variable from argument, and with a default value

bash, shell, unix

Solution

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 `'.'`”.

Problem

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 variable expansion methods and programs like `test` and `[` and `[[`, etc. Right now I'm just looking for ``` DIR=$1 or . ``` Meaning, my DIR variable should contain either what is specified in the first arg or the current directory. What is the difference between this and `DIR=${1-.}`? I find the hyphen syntax confusing, and seek more readable syntax. Why can't I do this? ``` DIR="$1" || '.' ``` I'm guessing this means "if $1 is empty, the assignment still works (DIR becomes empty), so the invalid command '.' never gets executed."

Original source

Related problems