nocl
nocl

Reputation: 3

Understanding the use of command substitution in bash

I would like to know what the difference between the two commands below is ?

ubuntu:~/bin$ (ls -A1 /home/ | wc -l) 
1

ubuntu:~/bin$ $(ls -A1 /home/ | wc -l)
1: command not found

If I put dir_count=(ls -A1 /home/ | wc -l) in a script i get the following error.

./two_args: line 24: syntax error near unexpected token `|'
./two_args: line 24: `dir_1_count=(ls -A1 "$dir_1" | wc -l)'

where as the following works:

 dir_count=$(ls -A1 /home/ | wc -l)

Upvotes: 0

Views: 89

Answers (3)

Karoly Horvath
Karoly Horvath

Reputation: 96258

$(command), is command substitution. It simply executes the command and substitutes the standard output of the command.

So if you want to set the variable, simply: dir_count=$(ls -A1 /home/ | wc -l)

About the rest of your code:

(ls -A1 /home/ | wc -l)

this one executes the command in a subshell. You probably don't want those parentheses.

$(ls -A1 /home/ | wc -l)

this one just doesn't make any sense, you substitute the result, so you get 1, and the shell will try to execute the command called 1.

Upvotes: 1

ruakh
ruakh

Reputation: 183231

(...) is just a special grouping operator. It runs ... in a subshell, meaning that it cannot modify the parent's execution environment (so, for example, (foo=bar) is useless, because the assignment will not survive past the end of the command), but is otherwise treated pretty normally (its standard output goes to standard output, etc.).


$(...) is a substitution; just like how $foo gets replaced with the value of the variable foo, $(...) gets replaced with the output of the command .... More precisely . . . like (...), it also runs ... in a subshell, but in addition, it captures the standard output of ..., and then ends up getting replaced with that output. So, for example, this:

"$(echo cd)" "foo$(echo bar)"

runs echo cd and captures the cd, and runs echo bar and captures the bar, and then runs the combined command cd foobar.

Upvotes: 0

danpan11
danpan11

Reputation: 191

To simplify the variable management in the script, I recommend you try the following:

dir_1_count=`ls -A1 ${dir1} | wc -l`

Use the character "`" to delimitate variables and store the result of a usual shell command in your script.

Remember to use the inverted apostrophe, not the single quote, copy the variable definition I just gave you.

Upvotes: 0

Related Questions