This is the third article of a series focused in Gnu Bash scripting. On the first article we’ve just created a simple script with commands, one after another. We also saw some variables use.
The second article covered some bash control structures. This one will cover redirections, pipes, and command substitution.
The good ol’ days
In the beginning there was a principle: one tool should do one thing and do it well. It was on the user to combine those tools in order to achieve the desired results.
Now we (admit it: sometimes you too could feel lost without a GUI) do (almost) everything with a mouse. But the command line is still there and some other times to write some commands or a script it’s easier than click on every element on the screen.
We can redirect the input or the output of a command before is executed. We can use this redirection to store the output of a command in a file. Or we can use input redirection to read some data from a file.
For example, if we want to store the current status (i.e. ls -l) of a folder in a text file to compare the changes later, we use the > operator like this:
ls -l > status.txt
This will redirect the standard output of ls -l to a file named status.txt. If status.txt already exists, will be overwritten. To append the standard output to an existing file, use the >> operator.
To redirect the standard input to a command use the < operator. For example:
mysql somedb < file.sql
To redirect standard error to some file, add the file descriptor 2 (file descriptor 1 is standard output (stdout), 0 is for input (stdin)) to the redirection:
command 2> file
Pay attention that there is no space between file descriptor number and the operator. If there were a space between them, that ‘2’ becomes a parameter. For example:
First command is “ls (file) something” and redirect the error output to status.txt. In the second command we see the error of our first command: file named something is not found.
Third command is ls files something and 2 (non of them exists) and redirect the standard output to status.txt. Errors (file not found) are printed on screen and in the fourth command we see that status.txt was left blank because there aren’t files named “2” or “something”.
We can combine redirections, like send stdout and stderr to a file, but the order of redirections is important. For example:
From the bash manual: the first commands directs only the standard output to file combined.txt, because the standard error was duplicated from the standard output before the standard output was redirected to combined.txt
On the second command, the standard output was redirected to file combined.txt and then the standard error was redirected to stdout.
From the bash manual: A pipeline is a sequence of one or more commands separated by one of the control operators | or |&.
The first operator connects the standard output of the first command to the standard input of the second. For example, if I don’t remember that I can use wildcards in the ls command and want to list every shell script on the current folder I can do a ls and filter the output with grep:
Perl people have a motto: «There’s more than one way to do it». I personally think it should apply (almost) everywhere.
The second operator, connects the standard error of the first command to the standard input of the second. For example, I’m using the command tr (that translates characters) to mock of error messages:
I’ve also set the LANG shell variable to change the output from spanish to english.
With command substitution we can execute a command within our script and use the output of that command. It’s easier to understand how it works with an example. The command seq is used to produce a sequence of numbers:
For example, we can use this output to create folders with sequential names with command substitution. We can use `command` or $(command) .
In this example we assign the output of seq 1 5 to the variable i, and use it in a for loop.
So far, we have enough to make the computer do (much of) the work for us. It’s on you to investigate those small tools that do one task but do it very good and integrate them via scripts or in the command line.
For the last article of this series, I’m gonna concentrate in the dialog program for creating a GUI (actually a TUI) to add interactivity to our scripts.