Shell 脚本输出数据

2021-09-21 17:29:54
admin
2034
最后编辑:admin 于 2021-09-26 10:28:35

文件描述符

Linux 系统中,一切皆为文件。包括文本文件、目录、各种硬件、输入、输出、报错……

Linux 用文件描述符来标识每个文件对象。文件描述符是一个非负整数,可唯一标识会话中打开的文件。

其中,bash shell 保留了前三个文件描述符(0、1、2)。

文件描述符缩写描述
0STDINshell 的标准输入
1STDOUTshell 的标准输出
2STDERRshell 的标准错误

STDIN:

对于 Shell 终端界面来说,标准输入就是键盘。

许多 bash 命令能直接接受键盘的标准输入,尤其是在命令行中没有指定文件时,例如cat命令。

STDOUT:

对于shell终端界面来说,标准输出就是终端显示器。

默认情况下,大部分bash命令会将输出导向标准输出中,也就是显示器。

STDERR:

报错信息虽然本质上也是输出,但 Shell 对于错误信息的输出处理,是和普通输出分开的。所以,在通过重定向符号 > 对 Shell 命令的输出进行重定向操作时,如果命令报错,错误信息是不会重定向到指定位置的。

shell出错时生成的错误信息都会发送到标准错误(STDERR)。

重定向错误

  1. 只重定向错误

因为标准错误的文件描述符是2,所以只重定向错误信息时,只需将2紧挨着放在重定向符号前,即 2>

此时,shell只重定向错误信息,而非普通数据。

实例:

输出一个不存在的文件的详情信息,将错误从定向到指定文件:

$ ll -a shell.sh 2> error.txt

执行后,查看文件里的内容信息:

$ cat error.txt 
ls: 无法访问 'shell.sh': 没有那个文件或目录

  2. 重定向错误和数据

如果想将错误信息和普通数据分别重定向到不同的指定文件中,则必须使用两个重定向符号,即 2> 和 1>

实例:

输出两个文件的信息,其中 hello.txt 文件存在,shell.txt 文件不存在。将标准输出重定向到 show.txt,错误信息重定向到 error.txt 中:

$ ll -a hello.txt shell.sh 1> show.txt 2> error.txt

执行后,查看对应文件里的输出内容:

$ cat show.txt 
-rw-r--r-- 1 root root 12 8月  17 13:51 hello.txt
$ cat error.txt 
ls: 无法访问 'shell.sh': 没有那个文件或目录

如果想将错误信息和普通数据一起重定向到同一指定文件中,则使用特殊重定向符号 &>

$ ll -a hello.txt shell.sh &> show.txt

执行后查看 show.txt 里的内容输出:

$ cat show.txt 
ls: 无法访问 'shell.sh': 没有那个文件或目录
-rw-r--r-- 1 root root 12 8月  17 13:51 hello.txt

在脚本中重定向输出

  1.临时重定向

如果要在脚本中生成一条错误消息,可以将单独 的一行(标准)输出重定向到STDERR文件描述符。

重定向到一个文件描述符时,重定向符号 > 后面要紧跟一个&。在平时保持重定向符号与文件描述符之间无空格的习惯。

echo "this is an error message" >&2

  2.永久重定向

上面是重定向一条信息输出,但如果有多条数据需要重定向,再去重定向每个echo就很麻烦。

取而代之,可以使用 exec 命令告诉shell在脚本执行期间重定向某个特定文件描述符。

exec 1> test.txt

可以在脚本执行过程中重定向标准输出(STDOUT)。

exec 会将标准输出(STDOUT)重定向到指定文件中,脚本发送给STDOUT的所有输出都会被重定向到指定文件。

注:exec 1> test.txt 要放在输出语句之前执行。

  3.同时进行标准输出与重定向

有时我们需要将输出同时发送到显示器和日志文件,而不用将输出重定向两次。这时,就用到了 tee 命令。

tee命令相当于管道的一个 Y 型接头。它将 STDIN 过来的数据同时重定向发往两处,一处是 STDOUT ,另一处是 tee 命令行指定的文件名:

tee filename

所以,可以使用 tee 命令配合管道来重定向命令输出。

实例:

#!/bin/bash
date | tee show.txt

执行结果:

$./test.sh  
2021年 09月 22日 星期三 14:14:06 CST
$ cat show.txt 
2021年 09月 22日 星期三 14:14:06 CST

注:默认情况下,tee 命令会在每次使用时覆盖其指定文件的内容。如果要追加传输,则必须使用 -a 选项。

date | tee -a show.txt

阻止命令输出

Linux 系统中有一个特殊的文件——null ,位于/dev/

该文件的特点正如其名,什么都没有。

Shell 输出到 null 文件里的任何数据都不会保存,全部都丢掉。

所以,当你不想显示某些 Shell 的输出内容,则可以将输出重定向到该文件,例如无需保存的报错信息。

ll -a shell.sh 2> /dev/null

正因 null 文件的特点,我们可以用它来快速清空一个文件。即只需将 null 文件重定向到想清空的文件即可:

dev/null > log.txt

这也是清除日志文件的一个常用方法。