Take the 2-minute tour ×
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?

Clarification:

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

Addendum:

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. –  user815423426 Oct 26 '11 at 21:57
add comment

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) –  user815423426 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 –  user815423426 Oct 26 '11 at 22:10
1  
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
add comment

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
  done
}
while true; do cmd; sleep 1; done
share|improve this answer
add comment

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.