There are certain commands or tricks that you start using as a sysadmin, which you simply incorporate into your arsenal and never really stop to analyze in-depth all the options or alternatives to them.
For me, one of those tricks is the backtick operator. I used it rather frequently when I programmed in Perl (which I don't use nowadays, but it seems to still have a loyal fan club - check this poll). In my Perl scripts, I would use the backtick operator to run a command in the operating system and return the output to continue the logic in the script.
[ You might also like: Bash scripting: How to write data to text files ]
The backtick operator is also available in shell scripts, and because it is so easy to combine with other commands, I started using it a lot. However, there is a more "recommended" way to do the same thing, using the
$ parens (parentheses) operator.
In this article, I show you the pros and cons of each one for use in shell scripts.
The basic functionality of backticks
The Open Group has a definition for the backtick operator, officially referred to as command substitution. This operator is not the single quote character, but another character known as the grave accent (
The idea is simple:
❯ echo "There are `ls | wc -l` files in this directory" There are 3 files in this directory
I have a very simple group of commands,
ls | wc -l that I use to list and count the number of files in the current directory. I can easily do this interactively and see exactly what the result is. Then I can embed it in my main
In a shell script, I could certainly perform the same thing, assigning the result of my count command to a variable and then use the variable later.
❯ file_count=`ls | wc -l` ❯ echo "There are $file_count files in this directory" There are 3 files in this directory
And of course, that would be better if the idea was to reuse the value or if the operation to perform was not so simple as in my example.
Embedding the commands using backticks is what I would classify as "quick and dirty tricks."
The $ parens
You can achieve the same result by replacing the backticks with the
$ parens, like in the example below:
❯ echo "There are $(ls | wc -l) files in this directory" There are 3 files in this directory
Here's another example, still very simple but a little more realistic. I need to troubleshoot something in my network connections, so I decide to show my total and waiting connections minute by minute.
❯ cat netinfo.sh #!/bin/bash while true do ss -an > netinfo.txt connections_total=$(cat netinfo.txt | wc -l) connections_waiting=$(grep WAIT netinfo.txt | wc -l) printf "$(date +%R) - Total=%6d Waiting=%6d\n" $connections_total $connections_waiting sleep 60 done ❯ ./netinfo.sh 22:59 - Total= 2930 Waiting= 977 23:00 - Total= 2923 Waiting= 963 23:01 - Total= 2346 Waiting= 397 23:02 - Total= 2497 Waiting= 541
It doesn't seem like a huge difference, right? I just had to adjust the syntax. Well, there are some implications involving the two approaches. If you are like me, who automatically uses the backticks without even blinking, keep reading.
Deprecation and recommendations
Deprecation sounds like a bad word, and in many cases, it might really be bad.
When I was researching the explanations for the backtick operator, I found some discussions about "are the backtick operators deprecated?"
The short answer is: Not in the sense of "on the verge of becoming unsupported and stop working." However, backticks should be avoided and replaced by the
$ parens syntax.
The main reasons for that are (in no particular order):
1. Backticks operators can become messy if the internal commands also use backticks.
- You will need to escape the internal backticks, and if you have single quotes as part of the commands or part of the results, reading and troubleshooting the script can become difficult.
- If you start thinking about nesting backtick operators inside other backtick operators, things will not work as expected or not work at all. Don't bother.
$ parens operator is safer and more predictable.
- What you code inside the
$parens operator is treated as a shell script. Syntactically it is the same thing as having that code in a text file, so you can expect that everything you would code in an isolated shell script would work here.
Here are some examples of the behavioral differences between backticks and
❯ echo '\$x' \$x ❯ echo `echo '\$x'` $x ❯ echo $(echo '\$x') \$x
You can find additional examples of the differences between backticks and
$ parens behavior here.
[ Free cheat sheet: Get a list of Linux utilities and commands for managing servers and networks. ]
If you compare the two approaches, it seems logical to think that you should always/only use the
$ parens approach. And you might think that the backtick operators are only used by sysadmins from an older era.
Well, that might be true, as sometimes I use things that I learned long ago, and in simple situations, my "muscle memory" just codes it for me. For those ad-hoc commands that you know that do not contain any nasty characters, you might be OK using backticks. But for anything that is more perennial or more complex/sophisticated, please go with the
$ parens approach.