When I execute the following in terminal:


echo $a    #output: 1
echo ($x)  #output: -bash: syntax error near unexpected token `$x'

Why are above outputs different? Also why are the following 2 outputs different:

$(echo foo) #output: -bash: foo: command not found
(echo foo) #output: foo

P.S.: I am trying to understand command substitution: $(command)

  • Note that the assignment in your title, a="($x)" is very different from the one in the question, a=($x) – ilkkachu Mar 21 at 12:30

You are mixing three different usages of parentheses in Bash: array definition, command substitution, and command grouping. Command substitution and command grouping are standard syntaxes and all POSIX sh-like shells support them. The array definition syntax is supported in shells that additionally have arrays.

Array Definition

Arrays are assigned to using compound assignments of the form

name=(value1 value2 … )

Your a=($x) creates an array with a single element, whose value is the value specified by $x, i.e. 1. When you echo an array by its name, in your case echo $a, it only echoes the first element of the array. So that's what you see, a 1 is printed to stdout.

If you have multiple elements in an array you can use "${arrayname[*]}" or "${arrayname[@]}" to access them. The first combines all array elements into a single argument while the second put each element as an individual argument.

This syntax is specific to bash and to other shells that allows for arrays in a similar way.

Command substitution (POSIX)

Command substitution allows the output of a command to replace the command itself. Command substitution occurs when a command is enclosed as follows:


Your command $(echo foo) performs shell substitution and is parsed to foo. So it is the same as you have typed foo. Since the command foo does not exist, bash complains about it.

Command grouping (POSIX)

Bash provides two ways to group a list of commands to be executed as a unit. When commands are grouped, redirections may be applied to the entire command list. For example, the output of all the commands in the list may be redirected to a single stream.

( list )

Placing a list of commands between parentheses causes a subshell environment to be created (see Command Execution Environment), and each of the commands in list to be executed in that subshell. Since the list is executed in a subshell, variable assignments do not remain in effect after the subshell completes.

Your command (echo foo) executes echo foo in a subshell, so foo is echoed. This has nothing to do with the command substitution. As the manual says, variable assignments in subshell do not remain in effect after the subshell completes. This can come handy if you want to write simple one-liners. For example, instead of

for l in {1..10}; do mycommand "$l"; done; unset l

You can write,

( for l in {1..10}; do mycommand "$l"; done )

Another helpful usage of a subshell is like using

( cd folder; ./mycommand )

instead of

cd folder; ./mycommand; cd -

Your command echo ($x) falls into none of these three categories, and bash reports a syntax error.

Quote your variables properly

It is also worth mentioning that you should quote your variable expansions whenever applicable (for example, when a string should contain the value of a variable). See When is double-quoting necessary? for details.

For example, the following would not invoke the particular constructs described above:


echo "$a"
echo "($x)"

Here, both calls to echo would output (1).

Links to bash manual pages




  • 2
    Thank you. I've revised a bit but feel free to make edits on it. I am not that good at guiding new users. – Weijun Zhou Mar 20 at 7:18
  • thanks for the detailed explanation Weijun – Sunny Mar 20 at 20:26

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.