3 ms·
edit: minor bugfix in example code A couple recommendations that make bash a much saner and avoid entire classes of problems: First, whenever you are expandin
by pdkl95 6y ago
edit: minor bugfix in example code
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.