I have a shell script with the following contents. I call it with ./script.sh. Echo successfully runs, but not when I try to save its output to a variable. The same is true for all commands I've tested so far; ls, pwd, node, etc…


echo foo
# foo

output=$("echo foo")
# command not found: echo foo

How come?

EDIT: Fix: the last echo is inside a string!

  • The only way I'm able to reproduce this is if I quote echo foo like: output=$('echo foo'). Or if I escape the space like output=$(echo\ foo). – jesse_b Mar 23 '19 at 14:33
  • 1
    can't reproduce here; do you have something odd in your zsh profile? – Jeff Schaller Mar 23 '19 at 14:33
  • I'm sorry, The last echo is supposed to reside in a string. – Audun Olsen Mar 23 '19 at 14:38
  • 1
    running "echo foo" would result in a similar error; what's your goal? – Jeff Schaller Mar 23 '19 at 14:39
  • Simply saving the output to a variable. But I see that it being inside a string may be my mistake… – Audun Olsen Mar 23 '19 at 14:41

It seems like you found the issue. You should quote only the string passed to echo and not the entire command itself:

output=$("echo foo")

Should instead be:

output=$(echo "foo")

If you want the output variable to contain the literal string echo foo then you should just set it as:

output='echo foo'

but could also do:

output=$(echo 'echo foo')
  • Thank you, this works. An additional question; if i replace echo with node, which was my initial goal, calling a node-script. I get command not found: node despite node being inside my $PATH variable. Which I checked by echoing path from inside the script. Thoughts? – Audun Olsen Mar 23 '19 at 14:47
  • Without seeing the command you're attempting to execute and your path I can't really speculate. – jesse_b Mar 23 '19 at 15:02
  • node script.js succeeds, output=$(node script.js) fails. Falls perfectly in line with the question title, actually. – Audun Olsen Mar 23 '19 at 15:14

As one might expect commands inside parentheses creates a subshell. But $() is not what you might think. It does not return the output of a command as a string it substitutes the output of a command into the shell. If you want proof try this: $(echo "echo 123")

Instead you want to use double quotes to capture it into a string instead of the array (the output split by spaces) being run on the shell.

output="$(echo foo)"

Note this isn't an issue specific to zsh it applies to bash as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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