首页 > 编程笔记 > Linux笔记 阅读:2

Linux输出重定向详解(附带实例)

输出重定向是指改变输出方向,不再输出到终端(显示器)上,而是输出到文件或其他设备中。

使用输出重定向的最大好处就是可以把命令结果保存到指定的文件中,我们可以到文件中对命令结果进行过滤或截取,并且命令执行结果是永久保存在文件中的,方便再次查看,这是在 shell 脚本中比较常见的操作。

Bash 支持的输出重定向符号如下表所示:

表:Bash 支持的输出重定向符号
类型 符号 作用
标准输出重定向 命令 > 文件 以覆盖的方式,把命令的正确输出重定向到指定的文件或设备中
命令 >> 文件 以追加的方式,把命令的正确输出重定向到指定的文件或设备中
标准错误输出重定向 错误命令 2>文件 以覆盖的方式,把命令的错误输出重定向到指定的文件或设备中
错误命令 2>>文件 以追加的方式,把命令的错误输出重定向到指定的文件或设备中
正确输出和错误输出同时保存 命令 > 文件 2>&1 以覆盖的方式,把正确输出和错误输出都保存到同一个文件中
命令 >> 文件 2>&1 以追加的方式,把正确输出和错误输出都保存到同一个文件中
命令 &>文件 以覆盖的方式,把正确输出和错误输出都保存到同一个文件中
命令 &>>文件 以追加的方式,把正确输出和错误输出都保存到同一个文件中
命令>>文件 1 2>>文件 2 把正确的输出追加到文件 1 中,把错误的输出追加到文件 2 中

Linux标准输出重定向

如下图所示,使用标准输出重定向将命令的正确执行结果保存到文件中。但是,如果命令执行错误,返回结果通过文件描述符 2 输出到命令行中,就无法重定向到文件中。


图 1 标准输出重定向

在输出重定向中,“>”代表的是覆盖,“>>”代表的是追加。

例如:
[root@localhost~]# ls -l /root/
total 4
-rw-------. 1 root root 1094 Jun 10 16:17 anaconda-ks.cfg
#首先执行ls命令,默认输出位置是屏幕
[root@localhost~]# ls -l /root/ > /root/out.log
#以>对ls命令的执行结果进行重定向,将结果输出到/root/out.log文件中
[root@localhost~]# cat /root/out.log
total 4
-rw-------. 1 root root 1094 Jun 10 16:17 anaconda-ks.cfg
-rw-r--r--. 1 root root    0 Oct 30 16:45 out.log
#查看文件内容
注意,将 ls -l 命令的结果通过重定向的方式写入文件 /root/out.log,但 ls 命令的结果并不是整体重定向并一次性写入到 /root/out.log 文件中的,而是逐步将命令执行结果写入到 /root/out.log 文件中的。

因此,在最初的命令结果写入到 /root/out.log 文件中后,/root/out.log 文件就已经存在于 /root/ 目录中,在 /root/out.log 文件中将见到 out.log 文件本身。
[root@localhost~]# pwd > /root/out.log
#将pwd命令结果以覆盖的方式写入/root/out.log文件
[root@localhost~]# cat /root/out.log
/root
#查看root/out.log文件

因为使用“>”会进行覆盖式写入,所以 out.log 中的原有数据将被 pwd 命令的结果所覆盖。在使用“>”时需要注意文件中是否有原有数据,以及原有数据是否可被覆盖。

如果不想覆盖文件中的原有数据,那么可以选择使用“>>”追加的方式进行写入。
[root@localhost~]# date >> /root/out.log
#使用追加重定向将date命令结果写入/root/out.log文件
[root@localhost~]# cat /root/out.log
/root
Tue Oct 31 17:38:15 CST 2023
#查看重定向执行结果
可以看到,在使用“>>”追加重定向后,原有 pwd 命令的执行结果还在,同时在下面新建了一行保存了 date 命令的执行结果。

Linux标准错误输出重定向

如下图所示,使用标准错误重定向将命令错误执行结果保存到文件中,但是如果命令执行正确,执行结果就通过文件描述符1输出到命令行中,无法重定向到文件中。


图 2 标准错误重定向

如果想要把命令的错误输出保存到文件中,那么使用正确的输出重定向是不成功的,例如:
[root@localhost~]# ls /root/xxxYYYZZZ >> /root/err.log
ls: cannot access '/root/xxxYYYZZZ': No such file or directory
#使用ls命令查看一个不存在的文件
#虽然使用了重定向符号,但是命令结果显示在命令行中
[root@localhost~]# ls /root/
anaconda-ks.cfg  err.log  out.log
[root@localhost~]# cat /root/err.log
#/root/目录中出现了err.log文件,但是文件为空
使用 ls 命令查看一个并不存在的文件,此时命令执行会报错,在命令返回错误结果的情况下,错误执行结果并没有通过重定向写入指定的 /root/err.log 文件,而是直接出现在当前命令行中。

因为“>>”表示对正确输出结果进行重定向,由于命令执行错误,正确输出结果为空,所以只创建了 /root/err.log 文件,并没有进行任何写入。在这种情况下,需要使用错误重定向进行写入,例如:
[root@localhost~]# ls /root/XXXYYYZZZ 2>> /root/err.log
#通过错误重定向,命令执行结果并没有在命令行中显示
[root@localhost~]# cat /root/err.log
ls: cannot access '/root/XXXYYYZZZ': No such file or directory
#命令执行报错结果显示在err.log文件中
在重定向过程中,2 表示错误输出,只有这样才能把命令的错误输出保存到指定的文件中。这里需要注意的是,错误输出的大于号左侧一定不能有空格,否则会报错。

Linux正确输出和错误输出同时保存到同一文件中

在重定向实际使用过程中,将正确输出和错误输出同时保存到某个文件中,比单独使用正确或错误重定向的概率高一些。因为在命令执行前,我们通常并不能确定命令会执行成功还是失败,所以,如下图所示,将正确输出和错误输出同时重定向到某文件中,这种既能保存正确输出又能保存错误输出的方式,更有利于我们保存命令执行的所有输出结果。


图 3 正确输出和错误输出同时重定向

命令执行结果如下:
[root@localhost~]# ls /root/ >> /root/together.log 2>&1
[root@localhost~]# ls /root/XXXYYYZZZ &>> /root/together.log
#将正确输出和错误输出全部重定向到/root/together.log文件中
#两种重定向方式依据个人习惯进行选择,执行结果相同
[root@localhost~]# cat /root/together.log
anaconda-ks.cfg
err.log
out.log
together.log
#第一条正确命令的输出追加保存了
ls: cannot access '/root/XXXYYYZZZ': No such file or directory
#第二条错误命令的输出也追加保存了

Linux正确输出和错误输出保存到不同文件中

我们还可以把正确输出和错误输出分别保存到不同的文件中,如下图所示:


图 4 正确输出和错误输出保存到不同的文件中

命令格式如下:
[root@localhost~]# ls >> list.log 2>> err.log
如果使用上述格式,那么命令的正确输出会写入文件 list.log,可以将其当作正确日志;而错误输出则会写入 err.log 文件,可以将其当作错误日志。笔者认为,如果想要保存命令的执行结果,那么这种方法更加清晰。

如果我们既不想把命令的输出保存下来,也不想把命令的执行结果输出到屏幕上,那么为了避免执行干扰命令,可以把命令的所有执行结果放入 /dev/null 中。大家可以把 /dev/null 当成 Linux 中的数据黑洞,任何重定向到 /dev/null 的数据都会被丢弃,并且不能被恢复。

命令如下:
[root@localhost~]# ls &>/dev/null
例如,输出到终端并写入文件。在上面的案例中,无论正确或错误,无论单个文件或多个文件,都将通过重定向的方式将命令执行结果写入指定的文件。使用 tee 命令并结合管道符可以将命令正确执行结果输出到命令行,同时也能将其写入文件,如下图所示。


图 5 输出到终端并写入文件

在图 5 中,用户通过标准输入(描述符 0)执行命令,在命令执行返回正确结果时,正确结果通过标准正确输出(描述符 1)传给管道符,管道符将命令执行结果交给 tee 命令,tee 命令将传递来的字符串输出到终端并写入文件。

命令如下:
[root@localhost~]# df -h | tee /root/tee.log
Filesystem      Size  Used Avail Use% Mounted on
...省略部分内容...
/dev/sda1        1014M   166M  849M  17% /boot
tmpfs           195M     0  195M   0% /run/user/0
/dev/sr0         7.9G   7.9G     0 100% /mnt
#可以看到,df命令执行结果出现在命令行中
[root@localhost~]# cat /root/tee.log
Filesystem      Size  Used Avail Use% Mounted on
...省略部分内容...
/dev/sda1        1014M   166M  849M  17% /boot
tmpfs           195M     0  195M   0% /run/user/0
/dev/sr0         7.9G   7.9G     0 100% /mnt
#df命令执行结果同时保存在文件中

相关文章