A couple recommendations that make bash a much saner and avoid entire classes of problems:
First, whenever you are expanding a list of args, use "$@"! That exact four character sequence expands to the properly quoted positional params ("$1" "$2" ...) with any necessary escaping included so each param expands as a single word. Almost all of the problems you've probably heard about bash "not handling spaces properly" or otherwise having problems with whitespace or strange characters in filenames are fixed by using "$@". If you're using arrays/hashes, you can get the same effect using "${somearrayorhash[@]}" (quotes included, just like "$@"). Removing the quotes or using the tradition $* is almost always a bug.
Second, always use explicit quotes/brackets! Forget that they were ever optional. Using "$@" fixes most of the whitespace-in-filename problems; expanding your variables with explicit quotes fixes the rest. Assuming these:
showargs() {
echo "$# args"
for i in "$@" ; do
echo "arg[${i}]"
done
}
declare -- name="filename with spaces\\!.txt"
declare -A h='([a]="b c" [foo]="'\''bar'\'' \"baz\" qu*x" )'
Instead of using the traditional shortcuts (which cause problems): showargs $name
# 3 args
# arg[filename]
# arg[with]
# arg[spaces\!.txt]
showargs ${h[*]} # or ${h[@]}
# 7 args
# arg[b]
# arg[c]
# arg['bar']
# arg["baz"]
# arg[qu*x]
Always using quotes/brackets simply does the right thing: showargs "${name}"
# 1 args
# arg[filename with spaces\!.txt]
showargs "${h[@]}"
# 2 args
# arg[b c d e]
# arg['bar' "baz" qu*x]
Bash still has it quirks and strange historical baggage, but in my experi4nce, using these two rules (and actually taking the time to read the bash(1) manpage...) changed writings shell scripts from an annoying mess of buggy arcane incantations into an actually sane(-ish) programming language. $ echo ‘pwd’
$ echo “pwd” $ echo $(pwd)
Incidentally: how does one type back quotes on an iPhone?!Edited to add: shellcheck [0] will flag the back quote usage if you're writing a bash script instead of a sh script.
`Thank you`!
I've been resisting learning (any more) bash for a while now, but I think I'm going to have to. This looks like it could reduce some of my terror at the insanities of shell scripts (why does one even need two quote characters that do different things?)