What is this form variable=$(...)
From the Bash manual (man bash
):
Command Substitution Command substitution allows the output of a command to replace the command name. There are two forms: $(command) or `command` Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting. The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).
(This holds true for all Bourne-like shells, i.e. sh
, ksh
, zsh
, bash
etc., and zsh
is also able to capture data with embedded NUL characters in this way)
The command
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
will assign the name of the directory where the script is located (while also changing all backslashes into forward slashes) to the variable basedir
. Any errors, warnings or other diagnostic messages that are outputted to the standard error stream will still be displayed on the terminal ($(...)
only captures the standard output of the command).
The shell will start by executing the innermost command substitution:
echo "$0" | sed -e 's,\\,/,g'
The output of that will be given as a string to dirname
, and the output of that will be assigned to the variable basedir
.
The double quotes are there to make sure that no word-splitting or filename globbing will be done, otherwise you may find that the script fails or produce strange output when $0
(the name of the script including the path used to execute it) contains a space character or a filename globbing character (such as ?
or *
).
It is in general a good idea to always quote expansions (variable expansions, command substitutions, and arithmetic expansions). See this question and its answers for an excellent explanation as to why this is a good idea.
If the script was executed as
$ /usr/local/bin/script.sh
then basedir
will get the value of /usr/local/bin
.
Or, on Cygwin:
$ bash c:\\Users\\Me\\script.sh
then basedir
will get the value of c:/Users/Me
. The double backslashes on the command line in this case is just to escape the single backslashes from the shell. The actual value of $0
is c:\Users\Me\script.sh
.
Another way of doing the same thing without using dirname
, echo
and sed
would be
basedir="${0//\\//}"
basedir="${basedir%/*}"
It means to run what is inside the parentheses in a subshell and return that as a value, in your case assigning that to varible
.
The varible=$(..)
called Command substitution and it's means nothing more but to run a shell command and store its output to a variable or display back using echo command. For example, display date and time:
echo "Today is $(date)"
and for store it to a variable:
SERVERNAME=$(hostname)
For more info: https://www.cyberciti.biz/faq/unix-linux-bsd-appleosx-bash-assign-variable-command-output/