Linux Bash Shell高级重定向操作--深入了解标准错误输出和标准输出

简介:

    一般来说一个程序的输出可分为标准输出和标准错误输出,这个已经众人皆知。但打印到屏幕上的输出一定是标准输出吗?答案是否定的!默认打印到屏幕上的输出不一定是标准输出。

举一个最常用的例子。我想通过nginx -v或ngxin -V查看nginx的版本信息,如果我只想要最后面的版本号,那我只需要用awk或cut处理就行。例如想获得“nginx version: nginx/1.2.7”中的“1.2.7”,理想的命令行是“nginx -v | grep nginx | cut -d '/' -f2”或“nginx -v | cut -d '/' -f2”或“nginx -v | grep nginx | awk -F '/' '{print $2}'”,但实际上依然会输出“nginx version: nginx/1.2.7”,你可能认为是不是我用echo的方法就能实现呢?也不是的。例如用命令行“echo $(nginx -v) | grep nginx | awk -F '/' '{print $2}'”或“echo $(nginx -v) | grep nginx | cut -d '/' -f2”也是不行的。

    但怎么就行了呢?答案是使用“2>&1 |”或“|&”(二者等价),将命令1的标准错误输出作为命令2的标准输入。

    解释:nginx -v的默认输出是标准错误输出(标准错误输出并不代表是执行返回值为1,如使用“echo $?”查看返回值为0(已正确执行))。例如我们可以测试一下,将“输出”(此时假设不知道它是标准输出还是标准错误输出)重定向到文件,再查看文件的内容。例如执行“nginx -v > test”时屏幕会输出“nginx version: nginx/1.2.7”,这表明屏幕上出现的是标准错误输出。当然了,你也可以用查看文件的方式“cat test”发现有这个文件,但内容却是空的,也说明这个命令没有输出标准输出。

    关于列截取。但在列截取的工具选择上,如果是可以将单字符作为间隔符,则最好是使用cut,经过测试发现,awk不能直接处理标准错误输出,即使将标准错误输出转化成标准输出后依然会有问题。例如“echo $(nginx -v) |& grep nginx | awk -F '/' '{print $2}'”和“echo $(nginx -v) | grep nginx | awk -F '/' '{print $2}'”以及“echo $(nginx -v) 2>&1 | grep nginx |& awk -F '/' '{print $2}'”的结果是完全一样的。而cut能处理标准错误输出但是有一种情况例外,“nginx -v |& grep nginx | awk -F '/' '{print $2}'”可以输出正确结果,“1.2.7”。

    除此之外,在测试的过程中发现,grep也不能直接处理标准错误输出。“echo $(nginx -v) 2>&1 | grep nginx > test”和“echo $(nginx -v) |& grep nginx > test”的结果都是test中没有任何内容,它只会输出“nginx version: nginx/1.2.7”。换成“nginx -v |& grep nginx”就能。

    tee也不能(tee不是标准的bash指令)!有点坑不是吗?

    参考:Bash Reference Manual的3.2.2 Pipelines http://www.gnu.org/software/bash/manual/bashref.html#Pipelines

    If ‘|&’ is used, the standard error ofcommand1is connected tocommand2’s standard input through the pipe; it is shorthand for 2>&1 |. This implicit redirection of the standard error is performed after any redirections specified by the command.

    因此,在类似调试出现问题时,确认是否是标准错误输出以及是否要处理也是一个值得考虑的点。




本文转自 urey_pp 51CTO博客,原文链接:http://blog.51cto.com/dgd2010/1419955,如需转载请自行联系原作者

相关文章
|
3月前
|
存储 Unix Linux
Linux I/O 重定向与管道
【8月更文挑战第17天】重定向在Linux中改变命令I/O流向,默认有">"覆盖输出至文件及">>"追加输出至文件末尾,便于保存结果;使用"<"从文件读取输入而非键盘,高效处理数据。文件描述符如0(stdin)、1(stdout)、2(stderr)标识I/O资源,支持读写操作。管道以"|"连接命令,使前一命令输出成为后一命令输入,如排序用户或找出CPU占用最高的进程,构建复杂数据处理流程。
46 9
|
3月前
|
Java Shell Linux
【Linux入门技巧】新员工必看:用Shell脚本轻松解析应用服务日志
关于如何使用Shell脚本来解析Linux系统中的应用服务日志,提供了脚本实现的详细步骤和技巧,以及一些Shell编程的技能扩展。
51 0
【Linux入门技巧】新员工必看:用Shell脚本轻松解析应用服务日志
|
3月前
|
存储 Unix Linux
Linux I/O 重定向与管道
【8月更文挑战第14天】输出重定向可将命令结果存入文件,如`>`覆盖写入或`>>`追加写入。输入重定向从文件读取数据,如`<`代替键盘输入。这些操作利用文件描述符(如0:stdin, 1:stdout, 2:stderr)管理I/O。管道`|`连接命令,使前一命令输出作为后一命令输入,便于数据处理,如排序用户`sort -t: -k3 -n /etc/passwd | head -3`或查找CPU占用高的进程`ps aux --sort=-%cpu | head -6`。
37 4
|
3月前
|
Unix Linux Shell
Linux I/O 重定向简介
Linux I/O 重定向简介
36 2
|
3月前
|
存储 Linux 数据处理
在Linux中,管道(pipe)和重定向(redirection)的是什么?
在Linux中,管道(pipe)和重定向(redirection)的是什么?
|
3月前
|
Shell Linux 程序员
详解shell 运行原理及Linux权限
详解shell 运行原理及Linux权限
|
4月前
|
Shell Linux C语言
|
4月前
|
Linux 数据处理 C语言
【Linux】基础IO----系统文件IO & 文件描述符fd & 重定向(下)
【Linux】基础IO----系统文件IO & 文件描述符fd & 重定向(下)
72 0
|
4月前
|
Shell Linux
Linux Shell 脚本入门教程:开启你的自动化之旅
Shell是一种计算机程序,它充当了用户与操作系统之间的接口。在Linux系统中,Shell允许用户通过命令行界面(CLI)来控制计算机。Shell脚本则是一种使用Shell语言编写的脚本,它可以自动执行一系列的命令,帮助用户实现任务自动化,提高工作效率。
132 2
|
4月前
|
Linux C语言 C++
【Linux】基础IO----系统文件IO & 文件描述符fd & 重定向(上)
【Linux】基础IO----系统文件IO & 文件描述符fd & 重定向(上)
48 0