Shell 脚本输出数据
- 2021-09-21 17:29:54
- admin
- 2034
- 最后编辑:admin 于 2021-09-26 10:28:35
文件描述符
Linux 系统中,一切皆为文件。包括文本文件、目录、各种硬件、输入、输出、报错……
Linux 用文件描述符来标识每个文件对象。文件描述符是一个非负整数,可唯一标识会话中打开的文件。
其中,bash shell 保留了前三个文件描述符(0、1、2)。
文件描述符 | 缩写 | 描述 |
0 | STDIN | shell 的标准输入 |
1 | STDOUT | shell 的标准输出 |
2 | STDERR | shell 的标准错误 |
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
这也是清除日志文件的一个常用方法。