Linux的I/O重定向和管道

在Linux系统中一切皆文件,当打开一个文件时,Linux会自动分配一个称为文件描述符(file description)的软链接,指向正在打开的文件。文件描述符是一个非负整数(通常是小整数),是内核为了高效管理已被打开的文件所创建的索引。所有执行I/O操作的系统调用都需要文件描述符。
数据流向有输入流(称为标准输入)、输出流,默认数据的输入流由键盘实现。默认的输出流是到当前的终端屏幕上。Linux系统里输出流又分为错误输出(称为标准错误输出)和正确的输出(称为标准输出)。
当一个程序刚启动时,会自动打开三个I/O设备文件:标准输入文件STDIN(STD即standard标准,IN即input输入),标准输出文件STDOUT,标准错误输出文件STDERR,分别得到文件描述符0,1,2。如果此时去打开一个新的文件,它的文件描述符会是3。
前面提到默认的STDIN,STDOUT和STDERR都是对应当前的终端窗口。既然是默认,就意味着可以修改。而I/O重定向就是把数据流传到非默认设备的其他地方。比如:可将命令执行结果应该输出到屏幕上,重定向后输出到文件中。管道就是把前一个命令的输出当做后一个命令的输入,实际上也是重定向。

1. I/O重定向

对于标准输入,标准输出和标准错误可以通过下面看到默认指向的设备

查看当前默认STDIN,STDOUT和STDERR对应的设备
[root@centos7 ~]# ll /proc/$BASHPID/fd
total 0
lrwx------. 1 root root 64 Apr  4 13:03 0 -> /dev/pts/5
lrwx------. 1 root root 64 Apr  4 13:03 1 -> /dev/pts/5
lrwx------. 1 root root 64 Apr  4 13:03 2 -> /dev/pts/5
lrwx------. 1 root root 64 Apr  5 02:50 255 -> /dev/pts/5

Linux为程序分别针对三种I/O设备提供了重定向的方法:
1)标准输入的重定向:描述符代码为0,使用0<或<实现标准输入的重定向,其中0可以省略。
2)标准输出的重定向:描述符代码为1,使用1>或>实现标准输出的重定向,其中1可以省略。
3)标准错误的重定向:描述符代码为2,使用2>或2>>实现标准错误的重定向。
4)另外,在Bash中有一个对应的设置可以设置禁用覆盖重定向:
set -C命令表示禁止将内容覆盖已有文件,但可追加。这个设置也可以使用强制覆盖的表达方式执行覆盖:>| file
set +C命令则表示允许覆盖

2. 标准输出重定向

对于标准输出可以通过">"和">>"重定向至文件中

将在终端pts/4执行命令的标准输出信息,重定向到pts/5对应的终端窗口。
注意:需要预先打开两个终端窗口
test.JPG

3. 标准错误输出重定向

和标准输出一样,也可以对标准错误重定向到文件中。就像用>和>>两个标准输出重定向符号一样,标准错误的输出信息也可用2> file进行重定向,以及将标准错误的追加输出重定向2>>file

[root@centos7 ~]# error_cmd
bash: error_cmd: command not found...
[root@centos7 ~]# error_cmd > /data/stderr.log
bash: error_cmd: command not found...
[root@centos7 ~]# error_cmd 2> /data/stderr.log
[root@centos7 ~]# cat /data/stderr.log
bash: error_cmd: command not found...
[root@centos7 ~]# ls /error
ls: cannot access /error: No such file or directory
[root@centos7 ~]# ls /error 2>> /data/stderr.log 
[root@centos7 ~]# cat /data/stderr.log
bash: error_cmd: command not found...
ls: cannot access /error: No such file or directory

4. 所有标准输出和错误的重定向

在上面的>和2>实现了标准输出和标准错误的分别重定向。也可以将所有输出信息,包括标准错误输出和标准输出都重定向到同一个文件中,有两种实现方式:
1)&> file
2)> file 2>&1
NOTE:第2中方法,一定要注意顺序,2>&1要放在命令的最后。其本质是先将标准输出重定向至文件中,再将错误重定向至标准输出,从而实现标准输出和错误的整体重定向

分别重定向标准错误到stderr.log文件和标准输出stdout.log文件
[root@centos7 ~]# ls /data/ /errordir > stdout.log 2> stderr.log
[root@centos7 ~]# cat stdout.log 
/data/:
stderr.log
[root@centos7 ~]# cat stderr.log 
ls: cannot access /errordir: No such file or director

合并标准输出和标准错误并实现覆盖重定向
[root@centos7 ~]# ls /data/ /errordir
ls: cannot access /errordir: No such file or directory
/data/:
stderr.log
[root@centos7 ~]# ls /data/ /errordir &> all.log
[root@centos7 ~]# cat all.log 
ls: cannot access /errordir: No such file or directory
/data/:
stderr.log
[root@centos7 ~]# ls /data/ /errordir > all2.log 2>&1
[root@centos7 ~]# cat all2.log 
ls: cannot access /errordir: No such file or directory
/data/:
stderr.log

5. 标准输入重定向

Linux中有许多命令需要用户利用标准输入设备输入信息,才可以进一步进行处理。比如:使用rm删除一个文件时,会询问yes或no。默认的标准输入设备是键盘,也可以像前面的标准输出和错误一样,用文件来代替终端窗口的键盘输入,实现标准输入的重定向
标准输入的重定向格式:command < file

利用标准输入的重定向,实现rm删除文件
[root@centos7 data]# ls
f1.txt  f2.txt
[root@centos7 data]# rm f1.txt 
rm: remove regular empty file ‘f1.txt’? y
[root@centos7 data]# echo y yes.txt
y yes.txt
[root@centos7 data]# echo y > yes.txt
[root@centos7 data]# cat yes.txt 
y
[root@centos7 data]# rm f2.txt < yes.txt 
rm: remove regular empty file ‘f2.txt’? [root@centos7 data]# 

利用标准输入重定向,实现备份issue文件
[root@centos7 data]# cat > issue.bak < /etc/issue
[root@centos7 data]# cat issue.bak 
\S
Kernel \r on an \m

6. 多行标准输入重定向

多行输入重定向的格式:command <<[-] 分隔符

你可能感兴趣的:(Linux的I/O重定向和管道)