how to chain commands in linux command line (with examples)

Sometimes you would want to run multiple commands in succession or simultaneously. This is usually useful when running processes or commands that is expected to run for a long period of time. This allows you to automate a process that include several commands that may or may not depend on the result of the previous command.

Linux command chaining is the method of combining several different commands such that each of them can execute in succession based on the operator that separate them. The important part of chaining is the operators that you use to combine them. These operators determine how the commands execute.

First, we will take a quick look at all the commonly used operators and its function. Later we will see examples on how it can be used with various commands. So, the list of operators are described below with the notations in brackets. This set of operators are used mostly to combine different commands and are easy enough to use directly from command line.

The above set are the most commonly used operators. However, there are several more that you probably should know. These set of operators are more of conditional in nature, or are used for grouping. They are very useful when writing long and complicated set of commands. They are therefore much more commonly found in shell scripts.

Now, let's look at some examples that will describe the function of these operators better. We will look at mostly some practical examples that you can use from the command line. We will use the operators one at a time and in combinations to simulate "real" world examples. Also, remember that each of these operators can be used within the shell script just as you use it directly from the command line.

Logical AND Operator

The logical AND operator will execute the commands that follow only if the current command is successful.

bash$ cd ~/temp/ && rm -fr *

The rm command will execute if and only if the cd command is successful. If for some reason, the cd command fails, this will make sure that the files in another directory (the current working directory) won't be accidentally deleted. You can chain several different commands using the AND operator.

bash$ cd ~/workspace/project/ && svn up && mvn clean install
bash$ cd /usr/src/linux && make && make modules_install && make install

The above two examples show how you can automate a compilation processes for your projects. Using the && operator makes sure that every command in the chain succeeds. This is probably the most used operator, especially in the command line.

Logical OR Operator

The logical OR operator acts quite the opposite to the AND operator. The command that follows will only be executed if the preceding command fails or the exit status is non-zero.

bash$ grep -nH apache /etc/passwd || grep -nH apache /etc/group

The grep command first checks if there is a user named apache (searches the passwd file). If it cannot find a user, then it will search if there is a group named apache in the group file.

bash$ find /usr/bin/ -iname "netstat" || find /sbin/ -iname "netstat" || find /bin/ -iname "netstat"

The above command searches different folders one after an other, till it finds the file by that name.

Semi-Colon Operator

This is useful when you want to execute a bunch of commands in succession and does not care about the exit state of the commands. This works best when the commands does not depend on the previous commands.

bash$ svn up; mvn clean install; rm -fr /tmp/*

The above commands will all execute no matter what. The mvn will clean and install even if the subversion (svn) fails to update successfully. Also, the rm command will clean up the tmp folder regardless of the exit state of mvn.

Pipe Operator

The pipe operator is useful when the second command wants to use the output of the first command as its input.

bash$ ls -l /path/ | grep -i filename.txt

The above command can probably be done in many different ways, but it shows you how the pipe operator works. The output of the command ls -l path is used by grep as its input. So, the above command will print out all the files in the directory /path that match the name filename.txt.

Ampersand Operator

The ampersand operator at the end of the commands will run the command in the background. You can run multiple commands in the back ground too, if you append each of them with the ampersand operator

bash$ rm -fr ~/documents/ & shred -uz ~/importantfiles/ & rm -r /tmp/*.txt

The above command will run the rm command to remove the files from the documents/ folder, while shredding the files in the importantfiles/ folder. This is a useful method when you want to run multiple commands simultaneously or at the same time.

Redirection Operators

The redirection operators can be used when you want to use a file or I/O stream other than the default standard input and standard output. You can use these operator to redirect either the standard input, standard output or both. Almost all commands will accept input using redirection operators.

bash$ sort < inputfile.txt

The above command will sort the contents of the file, named inputfile.txt. It will print out the sorted content into the standard output or the screen.

bash$ ls -l /path/ > ~/temp/filelist.txt

The above command will save the output of the ls command into a file name filelist.txt. It is useful in couple of different scenarios: if you want to view the output at a later time or if the output is too long to fit into a screenful or so.

bash$ sort < inputfile.txt > outputfile.txt

You can use both the input and output redirection operators together in the command. The above sort command will take the contents of inputfile.txt, sort them and then save them as outputfile.txt.

The other redirection operator is >>, which works exactly like the > operator but will append the output to the file rather than overwriting the output file stream.

The above six operators are probably the ones that you will regularly use from command line. As I mentioned, there are more that you can use, but they are usually useful when writing much more advanced shell scripts rather than having to type it out in the command line.