With other shells ∞
In Bash, dash, ash and sash, this works, but not in zsh:
a=ls b="-a -l" $a $b
In zsh ∞
The simple solution is to correct the code:
a="ls -a -l" eval "$a"
.. or
a="ls" b="-a -l" eval "$a" "$b"
This code works in both bash and zsh.
Advice ∞
- https://zsh.sourceforge.io/FAQ/zshfaq02.html#l10 [ 1 ] was http://zsh.sourceforge.net/FAQ/zshfaq02.html#l10
-
https://zsh.sourceforge.io/FAQ/zshfaq03.html#l18 [ 2 ] was http://zsh.sourceforge.net/FAQ/zshfaq03.html#l18
I got quite a bit more advice, but it never appeared in the archives: https://www.zsh.org/mla/workers/2009/
Good thing I kept a copy of the post so I can copy the content here for posterity.
The simple-but-insecure option would be:
setopt shwordsplit
Stéphane Chazelas gave a thorough answer, including the better and more universal way to do the code. I really appreciate that he went out of his way to explain things this thoroughly.
Cached response ∞
That behavior of those shells, inherited from the Bourne shell is the cause of half the bugs and especially the security ones in existing shell scripts. It’s been fixed in zsh.
See https://web.archive.org/web/20090706105130/http://zsh.dotsrc.org/FAQ/zshfaq03.html
Do
$=a
to explicitly request the word splitting. The equivalent of the other shells would be $=~a, that is request both word spitting and filename generation.
But chances are that you actually want:
eval $a
(eval "$a" is other shells)
if you want the content of $a to be interpreted as a command line and not as a list of arguments to a simple command.
setopt shwordsplit globsubst
enables the Bourne shell behavior. Same with “emulate sh”, if wou’re really keen on shooting yourself in the feet ;)
Note: to get zsh’s behavior in other shells, you’d do:
IFS=; set -f
But that would also disable filename generation everywhere, not only upon variable expansion.
Also note that zsh performs word splitting but not filename generation upon command substitution $(cmd) or `cmd` (and also the trimming of every trailing character, a bogus behavior of the Bourne shell which it did not fix).
Another thing to note (IMO another bug it did not fix) is that $a expands to no argument instead of en empty argument when $a is empty just like the other shells, which makes so that even in zsh, it’s generally safer to use quotes anyway just as in the other shells.
