Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

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?

share|improve this question
1  
Are the backticks in your 2nd command just OCR errors or do you really used them in your script? –  try-catch-finally Dec 28 '14 at 20:53
1  
Just as a remark: In bash that would work. –  Hauke Laging Dec 28 '14 at 20:54
1  
@HaukeLaging, that would work unless IFS was modified. –  Stéphane Chazelas Dec 28 '14 at 20:55
3  
@try-catch-finally But in this case the error message shows that he used quotes, not backticks. –  Hauke Laging Dec 28 '14 at 20:55
3  
@HaukeLaging, no zsh 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:59

2 Answers 2

up vote 8 down vote accepted

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 ...
share|improve this answer
    
Have you noticed the backticks in the 2nd command in the OP? –  try-catch-finally Dec 28 '14 at 20:52
    
Thanks @Stephane, this is very helpful, as usual. I am now hoping to make sense of this answer in the context of this other question. To do so, I tried >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
    
@user815423426 - have a look at Stéphane's answer here maybe. You might also glance at my own. The problem you're having is due to the shell's order of evaluations while parsing your command and the (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
    
Nevermind the problem with date is due to the fact that crontabrequires 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 evaluate the arguments stored in variable:

eval "$foo"

One can also evaluate expression with command substitution:

$(expr "$foo")

echoed variable (or otherwise printed) works as well:

$(echo "$foo")

These methods works fine at least in zsh and bash.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.