-------------------------------------- Command Substitution - $(unix command) -------------------------------------- -Ian! D. Allen - idallen@idallen.ca - www.idallen.com Unix shell Command Substitution is similar to variable substitution in that some text is being interpolated into the shell command line before a command is run. Variable substitution looks like this: $ x='hello there' $ echo "and I said $x to her" and I said hello there to her In Unix shell Command Substitution, it is the standard output of a separate command line that is substituted into the current command line: $ echo "the date is $(date) today" the date is Sat Jan 29 04:19:14 EST 2005 today The separate command line is executed by a separate shell process and all the standard output is captured and becomes the result of the substitution in the current command line before the current command line is processed by the shell: $ echo "the passwd file has $(wc -l &1 -s a nosuchfile ) # bundle stderr with stdout $ echo "foo contains '$foo'" foo contains 'ls: nosuchfile: No such file or directory 0 a' You don't have to put the output into a variable, you can use it directly: $ var=$( hostname ) $ echo "The name of this computer is $var." The name of this computer is idallen-home. $ echo "The name of this computer is $( hostname )." The name of this computer is idallen-home. $ echo "Hello. $( pwd ) is the current directory." Hello. /home/idallen is the current directory. Note that the text inside the parentheses of the command substitution is a full Unix shell command line, and all the rules for Unix shell command lines apply. In particular, the sub-shell that processes the command line inside those parentheses does so using the usual order of evaluation (quotes, redirection, variables, GLOBs) and then executes it. The output becomes part of the current command line. Unquoted blanks on the command line inside the command substitution parentheses are simply blanks occuring on a Unix command line; they don't affect the *output* of the commands being executed: $ echo "[$(pwd)]" [/home/idallen] $ echo "[$( pwd )]" [/home/idallen] $ echo "[$( pwd )]" [/home/idallen] Only the *output* of the commands being executed is captured. It doesn't matter how the command in parentheses is itself formatted. You can even put commands on separate lines (instead of using ';'), something often done in shell scripts to improve readability: $ foo=$( > echo "the date is:" > date > echo "today" > ) $ echo "$foo" the date is: Sat Jan 29 05:47:51 EST 2005 today Command substitution looks like variable substitution and it is done at the same time as variable substitution by the shell. In particular, this means that the output of a command substitution is subject to blank-splitting and GLOB expansion if the command substitution is not itself double-quoted and protected from the shell: $ touch a b c '*' # create a file name of asterisk * $ ls # ls output is by rows onto a terminal * a b c $ ls | cat # ls output is one column into a pipe or file * a b c $ echo "the files are $(ls)" # double-quoted command substitution the files are * # quoted ls output is one column a b c $ echo the files are $(ls) # WRONG! expansion is missing double quotes! the files are * a b c a b c # first * is GLOB expanded by shell! In the last example above, the output of the unquoted $(ls) command substitution expansion contains a GLOB character (the '*' file name) that the shell then GLOB-expands before it calls the echo command. Remember to double-quote your variables (including command substitutions)!