The following works in my shell (zsh):
> FOO='ls'
> $FOO
file1 file2
but the following doesn't:
> FOO='emacs -nw'
> $FOO
zsh: command not found: emacs -nw
even though invoking emacs -nw
directly opens Emacs perfectly well.
Why?
The following works in my shell (zsh):
> FOO='ls'
> $FOO
file1 file2
but the following doesn't:
> FOO='emacs -nw'
> $FOO
zsh: command not found: emacs -nw
even though invoking emacs -nw
directly opens Emacs perfectly well.
Why?
Because there's no command called emacs -nw
. There's a command called emacs
to which you can pass a -nw
option.
To store commands, you generally use functions:
foo() emacs -nw "$@"
foo ...
To store several arguments, you generally use arrays:
foo=(emacs -nw)
$foo ...
To store a string containing several words separated by spaces and have it split on spaces, you can do:
foo='emacs -nw'
${(s: :)foo} ...
You could rely on word splitting performed on IFS (IFS contains space, tab, newline and nul by default):
foo='emacs -nw'
$=foo ...
>my_wrapper.sh "some text" (date '+%d')
where the my_wrapper
is supposed to invoke the command date '+%d'
, but it doesn't work.
– Amelio Vazquez-Reina
Dec 28 '14 at 21:11
(subshell)
- the parser needs to read those at the same time it recognizes a variable expansion - which obviously cannot happen if the (
parens)
are within the expansion. You need eval
- or and alias
- in some form or another.
– mikeserv
Dec 28 '14 at 23:33
date
is due to the fact that crontab
requires escaping %d
as @Gilles mentioned here
– Amelio Vazquez-Reina
Dec 29 '14 at 14:03
For future readers it should be mentioned that the "standard" way of doing such thing is to eval
uate the arguments stored in variable:
eval "$foo"
One can also evaluate expression with command substitution:
$(expr "$foo")
echo
ed variable (or otherwise printed) works as well:
$(echo "$foo")
These methods works fine at least in zsh
and bash
.
IFS
issue inzsh
? – Hauke Laging Dec 28 '14 at 20:56zsh
behaves as you'd expect. When you type$cmd
, it runs the command whose name is stored in$cmd
.bash
(and most other Bourne like shells) invoke the split+glob operator on unquoted variables,zsh
fixed that. – Stéphane Chazelas Dec 28 '14 at 20:59zsh
way. – Stéphane Chazelas Dec 28 '14 at 21:03zsh
's behavior is also inconsistent. It splits$(cmd subs)
but not${vars}
. My preference is forksh93
's$IFS
handling - where the handling is consistent, and whitespace can either delimit per byte or sequence depending on how$IFS
is assigned. – mikeserv Dec 28 '14 at 23:26ksh
you're referring to is partly available in zsh (doubling whitespace in IFS prevents the special handling), the other way round is not a problem as that's just empty removal). – Stéphane Chazelas Dec 29 '14 at 16:01