The power of working on the Linux command line is evidenced nearly as much by the available operators as it is by the awesome collection of available commands. This post gives details and provides examples of how these many operators work.
Using |
The command line pipe, expressed by the character | (a vertical bar) is one of the most useful operators imaginable. It’s called a “pipe” and likely the vertical bar was selected to represent this operator because it resembles a physical pipe. What it does is pass the output of the command on the left side of the pipe to the command on the right side of the pipe through a special connection. For example, you could use a command like this one below to see which users are logged into the system:
$ who jdoe seat0 2024-06-20 10:37 (login screen) jdoe tty2 2024-06-20 10:39 (tty2) nancy tty3 2024-06-20 10:40 (tty2) shs pts/1 2024-06-20 10:56 (192.168.0.5)
If you only want to count the logins, on the other hand, you could use a pipe like this:
$ who | wc -l 4
If you want to see how many unique users are logged in, you’d have to work a little harder. You could reduce the username listing to the unique names like this:
$ who | awk '{print $1}' | sort | uniq jdoe nancy shs
That awk command in between the first and second pipes would reduce the output from the who command to just the first string on every line. The sort command then arranges these in alphabetical order so that the uniq command will include each username only once. That’s quite a few pipes, but they can cut the output down to just what we might want to see.
Using ||
In spite of the seeming similarity of | and ||, two vertical lines do not represent a double pipe. In fact, they don’t represent piping at all. Instead, the two vertical lines represent an “or” operator and they work in an interesting way. That is, if the command on the left side of a || works, the one on the right side won’t be run at all.
In the example below, the head command fails because it wasn’t run with root-level privilege (e.g., using sudo) and, thus, has no access to the /etc/shadow file. The echo command then runs after the error appears.
$ head -4 /etc/shadow || echo oops head: cannot open '/etc/shadow' for reading: Permission denied oops
If you want to see the effect without the error message, you could send the error output of the head command to /dev/null like this:
$ head -4 /etc/shadow 2>/dev/null || echo oops oops
The 2> operator redirects error output – in this case to /dev/null.
Using > and >>
The > and >> operators, unlike | and ||, are tightly related to each other. Still, they have a different though related function. If you run a command like one of those below, you add output of the fortune command to a file, creating it if is doesn’t already exist and overwriting it if it does.
$ fortune > readme $ cat readme 1 bulls, 3 cows. $ fortune > readme $ cat readme Does a one-legged duck swim in a circle?
Notice that, in the example above, the content of the file is replaced.
If you use >> instead, content will be appended to the file if it exists and used to create a new file if it doesn’t.
$ fortune >> readme $ cat readme Does a one-legged duck swim in a circle? fractal radiation jamming the backbone $ fortune >> ignoreme $ cat ignoreme It's all magic. :-)
Using & and && (and)
In a similar manner to | and ||, the & and && operators are very different in how they function in spite of the similarity in their appearance. A single & operator is used to run a process in the background. This means that you can go ahead and run other commands on the command line while it is still running. Here’s an example:
$ run-long-script & $
Notice how the prompt comes back to welcome your next command.
The &&, on the other hand, is more like the || operator, except that the command on the right side of the && runs only if the command on the left succeeds (rather than fails).
$ echo hello && echo goodbye hello goodbye
Using ;
The ; is an operator that allows you to run multiple commands on a single line. It simply separates them so they will run independently of each other. The commands will run in the order specified and each will complete before the next one is started.
$ sleep 3; echo 1; sleep 2; echo 2; sleep 1; echo 3 1 2 3
Using !
The ! (not) operator is one that allows you to express an exception when you type commands. For example, the command below will display the content of all of the files in the current directory except for the one named “ignoreme”.
$ cat !(ignoreme) Does a one-legged duck swim in a circle? fractal radiation jamming the backbone Virus transmitted from computer to sysadmins.
You can also use the ! with wild cards as in this example:
$ ls goodtimes ignoreme readme $ rm !(*me) $ ls ignoreme readme
When the rm command above runs, all files, except those ending in “me” are removed.
Using =, == and !=
The = sign, as you undoubtedly know, is used to assign a value to a variable. The == and != signs test for equality and inequality.
$ three=3 $ if [ $three == 3 ]; then > echo I like math > fi I like math $ if [ $three != 3 ]; then > echo "I do not trust math" > fi
Fortunately, three did equal 3 in the tests shown above, so we saw no output on the inequality test.
Using the escape character ()
The backslash character works as an escape character (at least for the Bourne shell). It allows other characters to be displayed without being interpreted. In the rather complex string below, every other character is simply displayed because of the backslash preceding it.
$ echo "'&|;()^'<>$ "'&|;()^'<>$
Wrap-up
It takes a while to become familiar with all of the available command operators, but they prove extremely useful on the command line and in scripts. An earlier post on &&, ||, and ! is available at Demystifying &&, !! and ! on Linux
Source:: , >>, &, &&, !, =, () and many more” >Network World