Bash Redirection
Contents |
Redirecting Input and Output
To redirect input or output, you use symbols following the command, including any options it takes. For instance, to redirect the output of the echo command, you could type something like this:
$ echo $PS1 > PS1.txt
The result is that the file PS1.txt contains the output of the command. This is the simbols that are used in Redirection:
Redirects that overwrite files
- > Creates a new file containing standard output. If the specified file exists, it’s overwritten.
$ ls > output1_ls.txt
Redirects that append to files
- >> Appends standard output to the existing file. If the specified file doesn’t exist, it’s created.
$ ls >> output2_ls.txt
Redirecting from standard error
- 2> Creates a new file containing standard error. If the specified file exists, it’s overwritten.
$ grep da * 2> grep_errors1.txt
- 2>> Appends standard error to the existing file. If the specified file doesn’t exist, it’s created.
$ grep da * 2>> grep-errors2.txt
- &> Creates a new file containing both standard output and standard error. If the specified file exists, it’s overwritten.
$ grep da * &> grep_output_and_error.txt
Redirecting file contents as input for programs
- < Sends the contents of the specified file to be used as standard input.
$ cat < grep_output_and_errot.txt
Redirecting standard input into programs
- << Accepts text on the following lines as standard input.
$ cat <<EOF This is standar input EOF
Redirection to both standard input and standard output
- <> Causes the specified file to be used for both standard input and standard output.
$ cat < grep_output_and_errot.txt > grep_output_and_errot2.txt
Practical uses of redirection
Sending output to a file
echo "newuser::200:200::/home/newuser:/bin/bash" >> /etc/passwd
This will append the line to the passwd file, effectively adding a user to the system. Normally, echo will send everything back to the console. Except, here we see ">>", this operator appends to the file mentioned. An alternative operator, ">", will replace all data in the file with the line- SO BE CAREFUL. Also, both will create a new file if the filename doesn't exist.
Sending output from a program to a file
You can use the same trick to tell a program to send its output to a file:
find / -name *.avi > movielist.txt
This sends all the names of the *.avi's on your filesystems mounted under / to movies.txt. You could also give find the -ls option to give the pathname.
Piping the output of one program through another
You can just as easily pass output to another program, just substitute the '>' or '>>' for '|'.
ps aux|grep keyword
Searches processes for 'keyword'. grep being a search/filtering program. (There happens to be a program which searches for processes and returns the process id, named pgrep) We could combine this with the AWK programming scripting language which will allow us to filter input/output. AWK is great for text manipulation. We will tell it to return a specific column, so we can see the process number.
ps aux|awk '/keyword/{print $2}'
Using the output of (piped) programs as command line arguments
We can also set the order something executes within a command line with `` (backticks). In the next example, we will execute the preceding statement first, telling it to kill -9 the results.
kill -9 `ps aux|awk '/keyword/{print $2}'`
Pasting into files directly
Of course you can get input ('<', '<<') in a similar way you would output. Here is an example:
Pasting text directly to a file:
cat <<EOF > file.txt
After pressing enter, everything you paste in the console will be send to 'file.txt'. Entering EOF close the file. Whats happening: cat, as we know, dumps output. Except this time, rather than dumping a file, we specify '-'. This tells cat to look for input from the keyboard. Normally, the output is dumped to the screen. However now the output, is sent to 'file.txt' via the '>' character.
Putting it all together
Typing/Pasting directly into gcc
cat <<EOF |gcc -o file -xc -
Here, we can freely type, or even paste some text from another window, directly into gcc, telling it to stop with EOF. In many cases the '-' character can be used similarly to '<' in that it takes standard input. Here it is passed from cat, but it can also take input from the keyboard.
Whether you are debugging something, or just wanting to be quick and neat- we can further simplify those repetitive tasks by telling the command line to do more than one task.
cat <<EOF |gcc -o file -xc - && ./file
We can manipulate this further by adding in an operator programmers will recognize, the double ampersand '&&'. Rather than an input/output operator, this is known as a logical operator. This basically says "if the first statement is true, then execute the second one". So in the example above, if the compilation was successful, ./file would be executed.
The semicolon character ';' which is a command separator for bash, can be used to indicate the end of a given command. This would be useful if you want to unconditionally run a series of commands on a single line. If the first execution returns an error, then the second would still execute regardless.