What does it mean in shell when we put a command inside dollar sign and parentheses: $(command)

72,694

Solution 1

Usage of the $ like ${HOME} gives the value of HOME. Usage of the $ like $(echo foo) means run whatever is inside the parentheses in a subshell and return that as the value. In my example, you would get foo since echo will write foo to standard out

Solution 2

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Could anybody help me to figure out how this command get executed?

Let's look at different parts of the command. BASH_SOURCE is a bash array variable containing source filenames. So "${BASH_SOURCE[0]}" would return you the name of the script file.

dirname is a utility provided by GNU coreutils that remove the last component from the filename. Thus if you execute your script by saying bash foo, "$( dirname "${BASH_SOURCE[0]}" )" would return .. If you said bash ../foo, it'd return ..; for bash /some/path/foo it'd return /some/path.

Finally, the entire command "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" gets the absolute directory containing the script being invoked.

$(...) allows command substitution, i.e. allows the output of a command to replace the command itself and can be nested.

Share:
72,694
KItis
Author by

KItis

software engineer

Updated on December 24, 2020

Comments

  • KItis
    KItis over 3 years

    I just want to understand following line of code in shell. It is used to get the current working directory. I am aware that $(variable) name return the value inside the variable name, but what is $(command) supposed to return? Does it return the value after executing the command? In that case, we can use ` to execute the command.

    CWD="$(cd "$(dirname $0)"; pwd)"
    

    Same output can be taken from the following line of code also in different version of shell

    DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    

    I am unable to understand the meaning of $(cd.. and $(dirname.

    Could anybody help me to figure out how this command get executed?

  • Jonathan Leffler
    Jonathan Leffler almost 11 years
    Yes; $(...) is a better way of writing a command than trying to use back quotes. Consider writing: gcclib=$(dirname $(dirname $(which gcc)))/lib using back quotes. Even before you get into the difficulties of doing it in Markdown, it is harder because you have to escape the backquotes of the nested commands, whereas you don't with the $(...) notation.
  • trysis
    trysis almost 9 years
    Technically, $(echo foo) creates a command substitution, not a subshell. The other current answer gets this right. I think command substitution is run in a subshell, sort of, but they are still different concepts.
  • Christian
    Christian over 7 years
    Sorry for being 3 years late to the party, but could you please explain why the statement works? You said dirname returns the path of the file executed (relative or absolute to the present working directory), cd changes the pwd to that directory, and pwd prints out the absolute path of the current working directory. But why are they joined by &&? And what will DIR hold if the cd fails?
  • Eliran Malka
    Eliran Malka over 7 years
    @trysis - command substitution definitely runs in a subshell, and so it's worth noting it.
  • Mitchell Tracy
    Mitchell Tracy about 7 years
    I understand that the backticks produce the same result as $(), but is the difference purely cosmetic? is there a reason to use one versus the other, apart from that the $() is more legible?
  • Charles Duffy
    Charles Duffy over 5 years
    @Christian, && prevents the pwd from running if the cd fails, such that DIR will be empty rather than having an incorrect directory.
  • Accountant م
    Accountant م about 5 years
    "Usage of the $ like $(echo foo) means run whatever is inside the parentheses in a subshell and return that as the value."...This is confusing, as this command $(echo foo) will try to run what is returned from the parentheses, it will first run echo foo then will try to run foo which gives an error