21

When I type ls -l $(echo file) output from bracket (which is just simple echo'ing) is taken and passed to external ls -l command. It equals to simple ls -l file.

When I type ls -l (echo file) we have error because one cannot nest () inside external command.

Can someone help me understand the difference between $() and () ?

codeforester
  • 39,467
  • 16
  • 112
  • 140
run4gnu
  • 333
  • 1
  • 2
  • 7

4 Answers4

31

$(cmd) substitutes the result of cmd as a string, whereas (cmd; cmd) run a list of commands in a subprocess.

If you want to put the output of one or more commands into a variable use the $( cmd ) form.

However if you want to run a number of commands and treat them as a single unit use the () form.

The latter is useful when you want to run a set of commands in the background:

(git pull; make clean; make all) &
codeforester
  • 39,467
  • 16
  • 112
  • 140
Barry Scott
  • 799
  • 6
  • 13
  • sorry, but still i dont get it... `variable=$(ls; ps)` `echo $variable` and eveyrting is correct , but `variable=(ls; ps)` gives syntax error `(ls; ps)` executes both commands `variable=(ls ps); echo $variable ` gives "ls" literally – run4gnu Aug 27 '16 at 17:40
9

Those are different things.

$() evaluates an expression (executing a command) like `` (backticks)

> (echo ls)
ls

> $(echo ls)
file1  file2

> `echo ls`
file1  file2

> echo $(echo ls)
ls
chenchuk
  • 5,324
  • 4
  • 34
  • 41
9

They are different, but there is a mnemonic relationship between them.

(...) is a command that starts a new subshell in which shell commands are run.

$(...) is an expression that starts a new subshell, whose expansion is the standard output produced by the commands it runs.

This is similar to another command/expression pair in bash: ((...)) is an arithmetic statement, while $((...)) is an arithmetic expression.

chepner
  • 497,756
  • 71
  • 530
  • 681
0

() is also used to create array in bash. See man bash:

Arrays are assigned to using compound assignments of the form name=(value1 ... valuen), where each value is of the form [subscript]=string.

$ arr=(a b c 'd f' e)
$ declare -p arr 
declare -a arr=([0]="a" [1]="b" [2]="c" [3]="d f" [4]="e")
Kai
  • 356
  • 1
  • 6