Bash Standard Input / Output Streaming and Redirection - AkuCode
Bash Standard Input / Output Streaming and Redirection - AkuCode
In Unix (of which Linux is a variety), everything is a stream of bytes. The streams are accessible as files, but three streams are rarely accessed by a filename. These are the input/output (I/O) stream attached to every command: standard input, standard output, and standard error. By default, these streams are connected to your terminal.
When a command reads a character or a line, it reads from the standard input stream, which is the keyboard. When it prints information, it is sent to the standard output, your monitor. The third stream, standard error, is also connected to your monitor, as the name implies, it is used for error messages. These streams are referred to by numbers, called file descriptors (FDs). These are 0,1, and 2, respectively. The stream names are also often contracted to stdin, stdout, and stderr.
I/O streams can be redirected to (or from) a file or into a pipeline.
Redirection: >,>>, and <
In chapter 1, you redirected standard output to a file using the > redirection operator. When redirecting using >, the file is created if it doesn’t exist. If it does exist, the is truncated to zero length before anything is sent to it. You can create an empty file by redirecting an empty string (that is, nothing) to the file:
printf “” > FILENAME
or by simply using this:
> FILENAME
Redirection is performed before any command on the line is executed. If you redirect to the same file you are reading from, that file will be truncated, and the command will have nothing to read. The >> operator doesn’t truncate the destination file; it appends to it. You could add a line to the hw command from the first chapter by doing the following:
echo exit 0 >> bin/hw
Redirecting standard output does not redirect standard error. Error messages will still be displayed on your monitor. To send the error messages to a file, in other words, to redirect FD2, the redirection operator is preceded by the FD. Both standard output and standard error can be redirected on the same line. The next command sends standard output to FILE and standard error to ERRORFILE:
$ printf ‘%s\n%v\n’ OK? Oops!>FILE 2>ERRORFILE
$ cat ERRORFILEbash4: printf: ‘v’: invalid format character
In this case, the error message is going to a special file, /dev/null. Sometimes called the bit bucket anything written to it is discarded.
printf ‘%s\n%v\n’ OK? Oops! > FILE 2>&1
Here of sending output to a file, it can be redirected to another I/O stream by usin>&N where N is to where standard output is going. If the order is reversed, the effect is different. The redirection sends a standard error to wherever standard output is currently going and then changes where the standard output goes. Standard error still goes to where standard output was originally directed:
printf ‘%s\n%v\n’ OK? Oops! 2>&1 > FILE
Bash has also a nonstandard syntax for redirecting both standard output and standard error to the same place:
&> FILE
To append both standard output and standard error to FILE, use this:
&>> FILE
A command that reads from standard input can have its input redirected from a file:
tr ,H wY < bin/hw
You can use the exec command to redirect the I/O streams for the rest of the script or until it’s changed again. All standard output will now go to the file tempFile, input will be read from the datafile, and error messages will go to errorfile without having to specify it for every command.
Reading Input
The read commands are a built-in shell that reads from the standard input. By default, it reads until a newline is received. The input is stored in one or move variables given as arguments:
read var
if more than one variable is given, the first word (the input up to the first space or tab) is assigned to the first variable, the second word is assigned to the second variable, and so on, with any leftover words assigned to the last one:
$ read a b c d
January February March April June July August
$ echo $a
January
$ echo $b
February
$ echo $c
March
$ echo $dApril May June July August
The bash version of reading has several options. Only the -r option is recognized by the POSIX standard. It tells the shell to interpret escape sequences literally. By default, read strips backslashes from the input, and the following character is taken literally. The major effect of this default behavior is to allow the continuation of the line. With the -r options, a backslash followed by a newline is read as a literal backslash and the end of input.
I’ll discuss the other option in chapter 15. Like any other command that reads standard input, read can get its input from a file through redirection. For example, to read the first line from FILENAME, use this:
read var < FILENAME
Pipelines
Pipelines connect the standard output of one command directly to the standard input of another. The pipe symbol (|) is used between the command:
$ printf “%s\n” “$RAMDON” “$RAMDON” “$RAMDON” “$RAMDON” | tee FILENAME6181126758908930
The tee command reads from the standard input and passes it to one or more files as well as to the standard output. $RANDOM is a bash variable that returns a different integer between 0 and 32,767 each time it is referenced.
$ cat FILENAME6181126758908930
Command Substitution
The output of a command can be stored in a variable using command substitution. There are two forms for doing this. The first, which originated in the Bourne shell, users backticks:
date=`date`
The newer (and recommended) syntax is as follow:
date=$(date)
Command substitution should generally be reserved for external commands. When used with built-in command, it is very slow. That is why the -v option was added to printf.
Summary
The following are the commands and concepts you learned in this chapter
Commands
- cat: Prints the contents of one or more files to the standard output
- tee: Copies the standard input to the standard output and one or more files
- read: A built-in shell command that reads a line from the standard input
- date: Prints the current date and time
Concepts
- Standard I/O streams: These are streams of bytes from which commands read and to which output is sent.
- Arguments: These are words that follow a command; arguments may include options as well as other information such as filenames.
- Parameters: These are entities that store values; the three types are positional parameters, special parameters, and variables.
- Pipelines: A pipeline is a sequence of one or more commands separated by |; the standard output of the command preceding the pipe symbol is fed to the standard input of the command following it.
- Line continuation: This is a backslash at the end of a line that removes the newline and combines that line with the next.
- Command substitution: This means storing the output of a command in a variable or on the command line.
Comments