5

This question already has an answer here:

I'm using Ubuntu 16.04 with Bash and I tried to read in Wikipedia, in here and in here, but I failed to understand what is the meaning of "command substitution" in shell-scripting in general, and in Bash in particular, as in:

$(command)

or

`command`

What is the meaning of this term?

Edit: When I first published this question I already knew the pure concept of substitution and also the Linux concept of variable substitution (replacing a variable with its value by execution), yet I still missed the purpose of this shell feature from the documentation for whatever reason or group of reasons.


My answer after question locked

Command substitution is an operation with dedicated syntax to both execute a command and to have this command's output hold (stored) by a variable for later use.

An example with date:

thedate=$(date)

We can then print the result using the command printf:

printf 'The date is %s\n' "$thedate"
  1. The command substitution syntax is $().
  2. The command itself is date.
  3. Combining both we get $(date) which its output is the result of the substitution (that we could get after execution).
  4. We display the output value hold by the variable with printf, per the command above.

Note: \n in printf is a line-break.

marked as duplicate by bahamat, Romeo Ninov, Jeff Schaller, Satō Katsura, Anthony Geoghegan May 9 '18 at 12:11

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 5
    OK, everyone needs to relax and stop accusing each other of trolling. If you don't like a question, then downvote or ignore it and walk away. If you feel you're being attacked in comments, then do not engage but flag and walk away. – terdon Apr 26 '18 at 8:19
  • 2
    Also related: What's the difference between $(stuff) and `stuff`? – Scott Apr 26 '18 at 17:57
  • Displaying the output of a command using command substitution and echo is a bad example of command substitution because 1) the output would have been displayed anyway, 2) printf is safer to use for variable data. The example could as well be written date | sed 's/^/Today is /' – Kusalananda Jun 11 '18 at 6:56
  • @Kusalananda I see your point that printing it immediately (with printf) is useless. I changed the phrasing a bit, from immediately to sometime later, is it more appealing? – user9303970 Jun 11 '18 at 15:46
  • The example might be thedate=$(date), followed by printf 'The date is %s\n' "$thedate". – Kusalananda Jun 11 '18 at 15:48
11
+50

"Command substitution" is the name of the feature of the shell language that allows you to execute a command and have the output of that command replace (substitute) the text of the command.

There is no other feature of the shell language that allows you to do that.

A command substitution, i.e. the whole $(...) expression, is replaced by its output, which is the primary use of command substitutions.

The command that the command substitution executes, is executed in a subshell, which means it has its own environment that will not affect the parent shell's environment.

Not all subshell executions are command substitutions though (see further examples at end).

Example showing that a command substitution is executed in a subshell:

$ s=123
$ echo "hello $( s=world; echo "$s" )"
hello world
$ echo "$s"
123

Here, the variable s is set to the string 123. On the next line, echo is invoked on a string containing the result of a command substitution. The command substitution sets s to the string world and echoes this string. The string world is the output of the command in the command substitution and thus, if this was run under set -x, we would see that the second line above would have been expanded to echo 'hello world', which produces hello world on the terminal:

$ set -x
$ echo "hello $( s=world; echo "$s" )"
++ s=world
++ echo world
+ echo 'hello world'
hello world

(bash adds an extra level of + prompts to every level of a command substitution subshell in the trace output, other shells may not do this)

Lastly, we show that the command inside the command substitution was run in its own subshell, because it did not affect the value of s in the calling shell (the value of s is still 123, not world).

There are other situations where commands are executed in subshells, such as in

echo 'hello' | read message

In bash, the read is executed in a subshell, which means that $message will not be changed in the parent shell, i.e. doing echo "$message" after the above command will echo an empty string (or whatever value $message was before).

A process substitution in bash also executes in a subshell:

cat < <( echo 'hello world' )

This too is distinct from a command substitution.

  • For bash 4.2 up, if shopt lastpipe is set, job control is not active, and the pipeline is not backgrounded, the last command does not run in a subshell. – dave_thompson_085 Jun 21 '18 at 8:20
  • You say, “There is no other feature of the shell language that allows you to do that.”  Well, at the risk of splitting hairs, you can do cmd₁ > myfile / read -r var < myfile / cmd₂ "$var".  If necessary, you can expand that to handle multi-line data. – G-Man Sep 27 '18 at 20:07
  • @G-Man Yes, and you may also write out a new shell script to a file and execute that. There is no other feature that provides a way of substituting a piece of text with the output of a command though. – Kusalananda Sep 28 '18 at 6:38
0
a=$(command)

will store the result value of command into the variable.

There is really no more to it.

As a side note, I believe:

a=`command`

has been deprecated and has the same meaning as above.

  • 3
    result here is the standard output of the command stripped of all its trailing newline characters (and some variations in between shells if the output is non-text). Note that `...` is the Bourne of csh syntax while $(...) is the Korn/POSIX syntax (with `...` still supported for backward compatibility) – Stéphane Chazelas Apr 26 '18 at 8:16
  • @StéphaneChazelas Thank you for valuable information, and feel free to edit the answer for it to include it. – LinuxSecurityFreak Apr 26 '18 at 8:48

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