0

Recently, i used echo command prefixing it with $. To my surprise what it resulted was an error. My command was something like this.

# !/bin/bash
$(echo 'a')

The error was..

./test1.sh: line 3: a: command not found

Can anyone explain what is happening here. Thanks in advance.

4

$(echo a) is a "command substitution". The $(...) will be replaced by the output of the command within. The output in this case is a, which the shell then tries to execute. The shell can't locate the command called a and you get the error message.

It is unclear what your intention with this was or what you expected to happen. It is highly unusual to want to execute the result of a command substitution.


Some programs output strings that should be evaluated by the shell. It is therefore possible to see code like

eval "$(ssh-agent)"

which evaluates (runs) the output of the given command. These commands have a strictly specified output and are generally considered safe to run in this way. In the example above, ssh-agent will start the SSH agent process and output a few commands that will set the appropriate environment variables that the ssh client later will need for using the agent, for example,

SSH_AUTH_SOCK=/tmp/ssh-Ppg1EO5eRIZp/agent.6017; export SSH_AUTH_SOCK;
SSH_AGENT_PID=6018; export SSH_AGENT_PID;
echo Agent pid 6018;

This is then evaluated by eval.

eval is used here rather than just simply using $(ssh-agent) since the output of the ssh-agent command is more a compound command. Without eval, the ; command terminators would net be special.

Example:

$ s='echo hello; echo world'
$ $s
hello; echo world
$ eval "$s"
hello
world
  • OTOH, eval "$(dircolors)" is a reasonable thing to do. Same with several other commands that follow that pattern, like gpg-agent. – derobert Apr 12 '18 at 18:16
  • @derobert Yes, and $(ssh-agent). Good point. – Kusalananda Apr 12 '18 at 18:18
1

You can use set -x to see what the shell is doing:

set -x
$(echo 'a')
  ++ echo a
  + a

The shell executes echo a and puts the output on the command line. This is the same as if you had tried to execute this command line:

a

The shell looks for a command a in the path (and even before in the function, alias, and hash lists), does not find it and thus throws an error.

It works if the output is a valid command:

$(echo 'ls')
  • can you tell me, what for actually we use $ other then calling a variable. – Ashu Apr 12 '18 at 19:08
  • @Ashu It is obviously also used for command substitution – your case. Besides it appears in computation (echo $((1+2+3))), string creation ($'foo\nbar' / $"foo") and (less shell related) in the regexes which bash understands ([[ foo =~ ^f..$ ]]). It is also used for modifying variables in several ways: ${foo#bar} – Hauke Laging Apr 12 '18 at 19:10

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.