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.

Following up on the top answer to this question, I thought I could:

1) Define a command:

cmd='for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "arguments" $x; done'

2) Run it on a loop as follows

while true; do "$cmd"; sleep 1; done

However, the above doesn't work, and I get the following

zsh: command not found for x in $(......
zsh: command not found for x in $(......
zsh: command not found for x in $(......

Any thoughts why?


If I run for x in $(my_command | grep keyword | cut -d" " -f1); do command2 "arguments" $x; done' it works perfectly.


I have noticed that if I use eval, it works, i.e.:

while true; do eval "$cmd"; sleep 1; done

runs the command cmd every second

share|improve this question
Does zsh have the same for construct? –  Kevin Oct 26 '11 at 21:55
@Kevin: Yes, I'll clarify that eval "$cmd" or just running the contents of cmd work. –  Amelio Vazquez-Reina Oct 26 '11 at 21:57

2 Answers 2

up vote 4 down vote accepted

By putting quotes around $cmd, you're asking the shell to run a command named exactly that. There is not command named "for x in $(..."; in fact on my system, there isn't even a command named "for" - it's a shell keyword. To run the contents of $cmd, you'll have to use eval.

share|improve this answer
Thanks @Shawn. Hhmm, but why does the above syntax work for watch then? (see the link to a related question at the beginning of the OP) –  Amelio Vazquez-Reina Oct 26 '11 at 22:05
Nevermind, I think that @Guilles explained that in the watch example "$cmd" is passsed as an argument to bash, which I guess explains why it does not need eval –  Amelio Vazquez-Reina Oct 26 '11 at 22:10
It is because the shell is expecting a string, which it interprets line-by-line; just as it would when running a script from a file. –  Shawn J. Goff Oct 26 '11 at 22:14

If you want to prepare a command for running inside the same shell, use a function.

cmd () {
  for x in $(my_command | grep keyword | cut -d" " -f1); do
    command2 "arguments" $x
while true; do cmd; sleep 1; done
share|improve this answer

Your Answer


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.