Render Data-Redirect

There is A blog Redirection was introduced briefly, but it was very shallow at that time. Now let's get a better understanding of redirection.

1 Standard File Descriptor

Linux uses a file descriptor to identify each file object.

The file descriptor is a non-negative integer that uniquely identifies files opened by a session. Each process can have up to nine file descriptors at a time.
The bash shell retains the first three file descriptors (0, 1, 2):

File DescriptorAbbreviationdescribe
0STDINStandard Input
1STDOUTstandard output
2STDERRStandard error

The shell uses the three file descriptors above to direct the shell's default inputs and outputs (including errors) to the location of the response.

1.1 STDIN

File descriptor 0 represents the standard input for the shell. For terminals, the standard input is the keyboard.
When we need input, we can use the input redirection symbol (<) to replace STDIN with the file specified by the redirection.

Many bash commands accept STDIN input, such as cat, which reads STDIN if no file is specified:

$ cat
test1
test1
test2
test2

Enter cat only on the command line, it will accept input from STDIN, enter a line cat to display a line.

We can have cat accept input from a file by entering a redirection symbol (<):

$ cat test.txt
 Rave Wave
hotel california
nothing's gonna change my love for you

$ cat < test.txt
 Rave Wave
hotel california
nothing's gonna change my love for you

1.2 STDOUT

File descriptor 1 represents the standard output of the shell. For terminals, the standard output points to the display.

By default, almost all commands direct output to STDOUT (i.e., the display).

We can use output redirection symbols (>, >) to direct output elsewhere, such as to a file.

1.3 STDERR

File descriptor 2 represents the standard error of the shell, and for terminals, the standard error points to the display as well.
By default, STDERR and STDOUT point to the same place, although the file descriptors assigned to them are different.

1.4 Redirection error

<and<< are standard input (STDIN) redirection symbols;
>and >> are standard output (STDOUT) redirection symbols;
What is the standard error (STDERR) redirection symbol?

We already know that the STDERR file descriptor is 2. In fact, the standard error (STDERR) redirection symbol is to place 2 before the redirection symbol >.
So the standard error (STDERR) redirection symbol is 2>.

Be careful:
There is no space between 2 > medium 2 and >.

Take an example of redirecting STDERR and STDOUT:

$ ls test1 no_this_file
ls: cannot access no_this_file: No such file or directory
test1

$ ls test1 no_this_file 2> error.log
test1

$ ls test1 no_this_file 2> std_error.log > std_out.log

$ cat std_error.log
ls: cannot access no_this_file: No such file or directory

$ cat std_out.log
test1

In the above command, Standard Output Redirection Symbol > can also be written as 1 >. Because STDOUT file descriptor is 1, > can be seen as a shorthand form of 1 >.

There is a special redirection symbol, &>, that directs all output generated by the command, including STDOUT and STDERR, to the same location:

$ ls test1 no_this_file &> out

$ cat out
ls: cannot access no_this_file: No such file or directory
test1

2 Redirect output in script

There are two ways to redirect output in a script:

  1. Temporary redirect output (a command is redirected once)
  2. Permanently redirect all commands in the script (once opened, all commands are redirected indifferently)

2.1 Temporary Redirection

If you want to redirect STDOUT to STDERR you can use >&2, you must add an &. before the file STDERR file descriptor 2. If you don't add &, > 2 redirects STDOUT to a file named 2.

Similarly, STDERR can be redirected to STDOUT using 2>&1.

Take an example 2>&1:

$ ls no_this_file  > out
ls: cannot access no_this_file: No such file or directory

$ ls no_this_file  > out 2>&1

$ cat out 
ls: cannot access no_this_file: No such file or directory

File no_this_file does not exist, so ls no_this_file produces STDERR, but STDERR cannot be redirected with >, so the error message is displayed on the screen;
Ls no_This_File > out 2>&1 redirects STDOUT to out file and STDERR to STDOUT at the same time, so the error information is written to out file.
Be careful:
Ls no_This_Write file 2 >&1 > out, and the error message will still be displayed on the screen.

2.2 Permanent redirection

Use the exec command to redirect a specific file descriptor during script execution.

Redirect STDOUT to file:

$ cat temp.sh
#!/bin/bash
exec 1>out
echo "test redirecting"
echo "======="
echo "author: miyan"

$ ./temp.sh
$ cat out
test redirecting
=======
author: miyan

Since exec 1>out redirects STDOUT to the out file, when the script is executed by. /temp.sh, there is no output, and all three lines of output information are in the out file.

3 Redirect input in script

Use the exec command to redirect a specific file descriptor during script execution.

Redirect STDIN to file:

$ cat out
test redirecting
=======
author: miyan

$ cat temp.sh
#!/bin/bash
exec 0< out
while read line; do
    echo "$line"
done

$ ./temp.sh
test redirecting
=======
author: miyan

4 List open file descriptors

lsof - list open files.
The lsof command lists all file descriptors open on the Linux system.

By default, lsof produces a lot of output and displays information about each file opened on Linux, including all processes running in the background and all users logged in to the system.

You can use -p to specify the PID (process ID), -d to specify the file descriptor number, and -a to intersect the specified options (AND operation):

$ lsof -a -p $$ -d 0,1,2
lsof: WARNING: can't stat() proc file system /run/docker/netns/default
      Output information may be incomplete.
lsof: WARNING: can't stat() proc file system /run/docker/netns/2ab0329edc51
      Output information may be incomplete.
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
zsh     27644 miyan    0u   CHR  136,6      0t0    9 /dev/pts/6
zsh     27644 miyan    1u   CHR  136,6      0t0    9 /dev/pts/6
zsh     27644 miyan    2u   CHR  136,6      0t0    9 /dev/pts/6

Special environment variable $$denotes the current process ID.
The output above shows:
Process 27644 has three file descriptors open (0, 1, 2).
COMMAND: The name of the running command;
PID;
USER: The login name of the process owner;
FD: file descriptor and access type (r for read, w for write, u for read and write);
TYPE: File type (CHR character type, BLK block type, DIR directory, REG regular file);
DEVICE: Device number;
SIZE: If there is one, it indicates the size of the file;
NODE: Node number of local file;
NAME: File name.

5 Prevent command output

You can redirect the output to a special file called a null file. There is nothing in the null file. Any data entered into the null file will not be saved and all will be discarded.

The standard location for null files is/dev/null.

6 Log messages

The tee command sends the output to both the display and the log file.
Tee is equivalent to the T-joint of a pipe. It sends input from STDIN to two locations simultaneously. One is STDOUT and the other is the file name specified on the tee command line.

Example:

$ whoami | tee out
miyan

$ cat out
miyan

7 instances

Convert csv file to sql statement:

$ cat member.csv
mitre,boy,23
rosie,girl,21

$ cat temp.sh                                                                                                                                                      
#!/bin/bash
if (( $# != 1 )); then
    echo "usage: $0 csvfile"
    exit 1
fi
outfile="sqlfile"
IFS=","
while read name gender age; do
    cat  >> $outfile << EOF
    insert into member (name, gender, age) values ('$name', '$gender', '$age');
EOF
done < $1

$ ./temp.sh member.csv

$ cat sqlfile
    insert into member (name, gender, age) values ('mitre', 'boy', '23');
    insert into member (name, gender, age) values ('rosie', 'girl', '21');

Be careful:
Why should I write the statement cat >> $outfile << EOF?
Since we can't enter content directly into a file via << EOF, we can only redirect content to a file via >>, so we did a transfer with cat here:
Content input is redirected to cat first, and then to file by cat output.

Keywords: Linux

Added by errorCode30 on Mon, 06 Sep 2021 19:43:19 +0300