Linux operators: Using |, >, >>, &, &&, !, =, () and many more

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