2

I raised a few server environments with Ubuntu and Bash, on "self managed shell" hosting providers like DigitialOcean, on which I ran Drupal/WordPress applications.

All that time I didn't have a necessity to use what's called "command substition".

I ask, what will be a problem, a "pattern" in which a Bash programmer would have to use this concept? Please give an example?

3

I use it with find a lot, such as:

tar cvf ../junk.tar `find .`

Also, as part of a poor-man's IDE:

vi `grep mysearcstring *.[ch]`

The above are command-line examples. I also use it in scripts a lot, and would be hard-pressed without it. The most common case is probably as mentioned above, to set shell variables from the output of a command:

NOW=`date`

I use back-quotes by old habit, but the $(command) syntax is far better since you can embed one inside another. With back-quotes, you have to know just where to put the escape \ characters and it's a nuisance.

6

Command substitution means 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)"

It is useful in situations where my command receives as parameter the output of another command or example.

  • 2
    That's an unfortunate example in that date could do the same thing with date +'Today is %a %b %e %H:%M:%S %Z %Y' and also because printf is preferable over echo when outputting variable data. – Kusalananda Jun 10 '18 at 19:58
  • Also, date | sed 's/^/Today is /'... Using a command substitution to display data using echo is simply not a good or even idiomatic example of the use of command substitutions. – Kusalananda Jun 11 '18 at 6:58
  • vfbsilva you might want to change the example to use printf and not use date? – user9303970 Jun 11 '18 at 14:07
  • I might, problem is than I will be answering another questions. You can accept the next answer I couldn't care less the point is im not here to discuss best practices I was just showing a concept which imho was properly presented than this became code golfing and I'm not on the mood – vfbsilva Jun 11 '18 at 18:26
4

From the Command Substitution subsection in the POSIX standard:

Command substitution allows the output of a command to be substituted in place of the command name itself.

Command substitutions allow for a handy way of making use of a command's output without the need for first writing it to a temporary file and then reading it in from that file. This is best done if the command's output is a short string on a single line.

Some people use command substitutions to collect output from a command even though the amount of output may be a multi-line document. This is generally not a good way of using command substitution. Instead, the standard Unix idiom of passing data between processing stages using pipelines or temporary files should be used.


Examples of command substitutions that I use:

For example, to figure out whether the current user is executing the script as root:

if [ "$( id -u )" -ne 0 ]; then
   echo 'This script requires root privileges, re-run with sudo' >&2
   exit 1
fi

The $(id -u) command substitution will be substituted with the output of id -u, which will return the UID (an integer) of the current user.

Another example. I'm using GnuPG to sign git commits. For GnuPG to work properly, I need to set GPG_TTY to the name of the current terminal device in my interactive shell's initialization file. I do this with

export GPG_TTY="$( tty )"

This sets GPG_TTY to something like /dev/ttyp4 depending on what the current terminal device is in the shell session.

Another example. I have a script that has to treat running on a Solaris machine as a special case:

case "$( uname -s )" in
    SunOS)
        # code specific for Solaris
        ;;
    *)
        # code for all other Unix platforms
esac

Another example. The getconf PATH command returns the "default path" for the current system. I use it under some circumstances to reset the PATH variable to a "sane default" value:

PATH="$( getconf PATH )"
2

Another example:

  • In Docker you can clean off stopped containers using:

    docker rm containerID containerID containerID ...`
    
  • You can also get the ids of the containers that have stopped running with:

    docker ps -q -f "status=exited" 
    
  • So you can clean off all the stopped containers with:

    docker rm $(docker ps -q -f "status=exited")
    

... where the ids produced by docker ps are substituted to the $(docker ps...) string to be used by the docker rm command.

2

The implementation pattern that makes this usage necessary is that Unix shells execute each non-builtin command in a child process. The child process cannot modify the context of its parent. Command substitution can cause the shell to use textual output of a non-builtin command as if it had been written in the shell script or typed on the command line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.