The redirections and file descriptors are essential when working with the command-line interface. Knowing how I/O streams work helps you understand redirections even better.
In this article, you'll learn how to redirect stdout/stderr to a file in Bash.
Standard I/O Streams
When a command executes in Bash and other Linux shells, it uses three standard I/O streams. These I/O streams represent a system that allows programs to exchange data with their environment through input and output operations.
The standard I/O streams are:
- 0 -The standard input stream (stdin).
- 1 - The standard output stream (stdout).
- 2 - The standard error stream (stderr).
Each stream has assigned a numeric value, a file descriptor that helps operating systems keep track of open files.
0 - stdin: Standard Input Stream
Standard input (stdin) is a data stream from which a program reads. It is associated with the keyboard or a pipe in the case of an interactive shell.
The standard input stream is inherited from the parent process. This means the child process reads its input from the same source as the parent process. However, the standard input can also be explicitly redirected.
The file descriptor for standard input is 0 because standard input is the first file opened when a process starts.
ls command, by default, lists the current working directory contents:
In this case, there is no need to provide standard input.
whoami command prints the current user's username. It does not need any input from the user:
man only provides detailed info about the command if a user inputs a command name in the stdin.
For example, get the cat manual page with:
echo utility prints the text provided in the standard input as well:
echo "This is a sentence!"
stdin in Scripts
1. Create a script called script1.sh in Vim with:
Note: Always save script files with the sh extension.
2. Paste the following:
#!/bin/bash<br>read command<br>man $command
3. Save and exit the file.
4. Run the script with:
5. Provide the command name the script asks via stdin:
For example, usermod:
The script uses the stdin of
usermod to print the manual page for the command.
This script uses
read to request a command name via the standard input. Next, the input is used by
man to print the manual page.
1 - stdout: Standard Output Stream
Standard output (stdout) is a stream where a program writes output data. The program asks for data transfer with the write operation. The file descriptor for stdout is 1.
The standard output stream is associated with the terminal where the program is running. This means the terminal shows the program output. However, the standard output stream can be redirected to a file or another device.
Not all commands have stdout. For example, commands to create, move, or delete files do not generate any output unless there is an error.
2 - stderr: Standard Error Stream
Standard error (stderr) is a data stream that facilitates communication between a program and its environment. It provides a distinct channel to manage and display error messages separately from the standard output. The stderr initiates data transfers using the write operation, and the file descriptor for standard error is 2.
In most command-line environments, the standard error is used with standard output for a comprehensive program behavior overview. stdout and stderr are printed together in the terminal but often separated or shown in different colors. This segregation of normal output and error messages enables users to understand better the nature of issues a program encounters during its execution.
For example, to see both the stdout and stderr, run
ls for two directories (the existing Home directory, and the newdirectory, which doesn't exist on the system).
ls ./ newdirectory
The output prints:
- The error message ls: cannot access 'newdirectory': No such file or directory - an example of stderr.
- The Home directory contents - examples of stdout.
Redirecting stdout and stderr
Redirection is a way to use one program's output as input to another file or program. In most cases, streams are redirected to files or other streams using n>. The n operator represents the file descriptor number.
Redirect stdout and stderr to a File
To redirect a command's stdout and stderr to a file, use
&> without operators:
command &> [file_name]
For example, the command
ls ./ newdirectory lists the current directory contents and the error message in the terminal.
However, run the command to redirect stdout and stderr to a file:
ls ./ newdirectory &> complete_output
The terminal shows no output because both stdout and stderr have been redirected to the complete_output file.
Redirect stdout and stderr to Separate Files
Redirecting stdout and stderr to separate files enables users to review the output and error messages individually without cluttering the terminal.
The syntax for redirecting stdout and stderr to separate files is:
command > [output_file_name] 2> [error_file_name]
The syntax includes:
command > [output_file_name]- Redirecting stdout to the specified output file.
2> [error_file_name]- Redirecting stderr to the specified file.
For example, run the command:
ls ./ newdirectory > output 2> error
The terminal shows no output because:
lsstdout is redirected to the output file.
- Error message related to newdirectory not existing is redirected to the error file.
Verify by checking the file in the current directory:
Each file contains different output parts. The
cat command does the same:
Redirect stderr to stdout
It is common to redirect stderr to stdout to consolidate them into a single file for more straightforward analysis. The result is having error messages sent to the same location as standard output.
The syntax is:
command > [file_name] 2>&1
The command consists of:
> [file_name]- Directs the stdout to the specified file.
2>&1- Redirects the stderr to the same location as the standard output.
For instance, redirect the
ls ./ newdirectory stdout to the results file and stderr to the same location with:
ls ./ newdirectory > results 2>&1
The output is once again excluded from the terminal but is present in the results file:
The order in the redirection command is crucial. For instance, the command in the following syntax only redirects the standard output to the file. The stderr gets redirected to the terminal.
The problematic syntax is:
command 2>&1 > [file_name]
The issue is:
2>&1- Redirects stderr to the same location as stdout. However, since stdout has not been redirected yet in this syntax, stderr remains directed to the terminal.
> [file_name]- Redirects stdout to the specified file.
For instance, run:
ls ./ newdirectory 2>&1 > results1
The terminal shows the error message.
The results1 file contains only the stdout.
Redirect stdout to a File
To redirect only standard output to a file, run:
command 1> [file_name]
ls ./ newdirectory 1> out1
The terminal prints the error message, but the stdout is redirected to out1.
Verify the results with:
An even simpler option is to omit the number, as the command defaults to the standard input stream:
command > [file_name]
For instance, run:
ls ./ newdirectory > out2
The results are the same.
Redirect stderr to a File
To redirect the stderr to a file, use
command 2> [file_name]
ls ./ newdirectory 2> err1
cat command verifies the stderr is in the err1 file. However, the stdout is printed in the terminal.
After reading this article, you know what standard input streams are and how to redirect stdout and stderr to file in Bash.
Next, learn how to use the Linux exec command.