Linux管道只传到错误信息(stderr)——从一个小问题写起
2014-10-09 00:00
1051 查看
摘要: 对shell输出的错误信息进行过滤处理,使用管道处理标准错误信息(stderr)
使用该脚本时,MySQL的提示为:
第二行的提示其实没啥用,但是又不愿意使用 2>/dev/null 把所有错误信息都屏蔽掉。强迫症表示要干掉这条错误信息!
如果这时又要将输出信息导出到文件的话,我们能从很多博客或者教材中看到这样的写法:
然而,这样的话,标准输出(stdout)和错误输出(stderr)都到一起了,如果我们要将两个输出分开到两个文件存放(对!人生苦短,就是要这么钻牛角尖和丧心病狂)。
用这个来模拟问题就是:标准输出(stdout)导出到/tmp/aa文件,错误信息(stderr)中只留下”fff“文件的这条,其他的过滤
这样,正确信息导出到/tmp/aa文件中,错误信息中过滤了不想要的信息。
自己琢磨应该是这么回事:
2>&1 1>/tmp/aa
bash处理输出时,先碰到了”2>&1“,于是把错误信息(stderr)输出到标准输出(stdout)的位置(此时是默认位置,屏幕)。之后碰到了”1>/tmp/aa“,于是把原来的标准输出(stdout,不考虑被导过来的错误信息)输出到指定的文件(此时已被指定到/tmp/aa文件)
1>/tmp/aa 2>&1
bash处理输出时,先碰到了”1>/tmp/aa“,于是把标准输出(stdout)输出到指定文件(/tmp/aa文件)。之后碰到了”2>&1“,于是把错误信息(stderr)输出到标准输出(stdout)的位置(此时已被指定到/tmp/aa文件)
以上的也只是我自己瞎捉摸来帮助自己理解的。真实原因我不清楚,有个疑问就是:”1>/tmp/aa 2>&1“输出到文件的顺序并没有那么一致的顺序。按照我琢磨的,应该是先标准输出(stdout)后错误信息(stderr)。实际文件中的顺序为先错误信息(stderr)后标准输出(stdout)。
碰到问题
在自己编写的一个小脚本中,碰到这个一个小问题:问题背景:
在脚本中多次导出数据,为了不用重复输入密码,在运行时,使用read读取用户输入,将密码存入变量。将mysql的命令中使用该变量,此时mysql提示在命令行直接输入密码不安全(其实他人无法看到密码):# 脚本读取使用密码的一段为: read -s -p "Enter Password: " passwd mysql -uroot -S xxx -p$passwd -e "xxx" > xxx.sql
使用该脚本时,MySQL的提示为:
Enter password: Warning: Using a password on the command line interface can be insecure.
第二行的提示其实没啥用,但是又不愿意使用 2>/dev/null 把所有错误信息都屏蔽掉。强迫症表示要干掉这条错误信息!
问题内容:
将标准输出(stdout),即导出的数据,重定向到文件保存。将输出的错误信息(stderr)中提示在命令行中使用密码不安全的Warning过滤掉(程序员只关心error,无视warning :) ),同时,不影响其他错误信息的输出(不被过滤掉,也不会混到导出的数据中)。求解过程
在Linux的bash中,可以将命令的标准输入(stdin)、标准输出(stdout)、标准错误输出(stderr)通过数据流重导向导入到文件,这可以方便我们记录很多信息。管道的短处
在Linux中,管道”|“是经常使用的命令。可以很方便地利用一个命令来处理上一个命令的输出,准确的说是可以处理上一个命令的标准输出(stdout),管道并不能处理上一个命令的错误输出信息(stderr),如下:# /tmp 目录下存在两个t开头的文件,不存在名为fff和sss的文件 # 这条命令的输出中包含两行标准输出(stdout)和两行标准错误输出(stderr) [root /tmp ]$ ll t* fff sss ls: cannot access fff: No such file or directory ls: cannot access sss: No such file or directory -rw-r--r-- 1 root root 29 Oct 8 15:11 t -rwxr--r-- 1 root root 291 Sep 28 18:00 t.sh # 无论grep过滤的关键词是什么,错误输出(stderr)的两行都在 [root /tmp ]$ ll t* fff sss | grep "fff" ls: cannot access fff: No such file or directory ls: cannot access sss: No such file or directory [root /tmp ]$ ll t* fff sss | grep "t.sh" ls: cannot access fff: No such file or directory ls: cannot access sss: No such file or directory -rwxr--r-- 1 root root 291 Sep 28 18:00 t.sh
数据流重导向和管道
当然,我们可以使用 2>&1 的数据流重定向,将错误输出(stderr)导向标准输出,这里很多人都知道:# 在命令后加上 2>&1 就能使grep也能够过滤原来标准错误输出(stderr)的内容了 [root /tmp ]$ ll t* fff sss 2>&1 | grep "fff" ls: cannot access fff: No such file or directory [root /tmp ]$ ll t* fff sss 2>&1 | grep "t.sh" -rwxr--r-- 1 root root 291 Sep 28 18:00 t.sh
如果这时又要将输出信息导出到文件的话,我们能从很多博客或者教材中看到这样的写法:
[root /tmp ]$ ll t* fff sss 1>/tmp/aa 2>&1 [root /tmp ]$ cat aa ls: cannot access fff: No such file or directory ls: cannot access sss: No such file or directory -rw-r--r-- 1 root root 29 Oct 8 15:11 t -rwxr--r-- 1 root root 291 Sep 28 18:00 t.sh
然而,这样的话,标准输出(stdout)和错误输出(stderr)都到一起了,如果我们要将两个输出分开到两个文件存放(对!人生苦短,就是要这么钻牛角尖和丧心病狂)。
用这个来模拟问题就是:标准输出(stdout)导出到/tmp/aa文件,错误信息(stderr)中只留下”fff“文件的这条,其他的过滤
问题解决方法
这样其实也很容易,具体的方法就是:将”1>/tmp/aa“和”2>&1“位置对调下![root /tmp ]$ ll t* fff sss 2>&1 1>/tmp/aa | grep "fff" ls: cannot access fff: No such file or directory [root /tmp ]$ cat aa -rw-r--r-- 1 root root 29 Oct 8 15:11 t -rwxr--r-- 1 root root 291 Sep 28 18:00 t.sh [root /tmp ]$
这样,正确信息导出到/tmp/aa文件中,错误信息中过滤了不想要的信息。
自己总结
当时刚看到对调下就能产生这么大的差别时,心里默念了句:”哎呀,我x,还能这么用,我当初数据流白学了“自己琢磨应该是这么回事:
2>&1 1>/tmp/aa
bash处理输出时,先碰到了”2>&1“,于是把错误信息(stderr)输出到标准输出(stdout)的位置(此时是默认位置,屏幕)。之后碰到了”1>/tmp/aa“,于是把原来的标准输出(stdout,不考虑被导过来的错误信息)输出到指定的文件(此时已被指定到/tmp/aa文件)
1>/tmp/aa 2>&1
bash处理输出时,先碰到了”1>/tmp/aa“,于是把标准输出(stdout)输出到指定文件(/tmp/aa文件)。之后碰到了”2>&1“,于是把错误信息(stderr)输出到标准输出(stdout)的位置(此时已被指定到/tmp/aa文件)
以上的也只是我自己瞎捉摸来帮助自己理解的。真实原因我不清楚,有个疑问就是:”1>/tmp/aa 2>&1“输出到文件的顺序并没有那么一致的顺序。按照我琢磨的,应该是先标准输出(stdout)后错误信息(stderr)。实际文件中的顺序为先错误信息(stderr)后标准输出(stdout)。
one more thing
如果有人知道具体怎么解释,或者有管道这方面的资料的话,欢迎告诉我相关文章推荐
- web服务迁移到linux后无法显示错误信息的问题,只显示500
- Linux下父进程通过管道发送文件名给子进程,子进程获取文件名后首先判断文件是否存在,不存在,通过管道返回错误信息,存在,将文件内容返回给父进程
- Linux基础备忘_01:audit2allow的错误信息输出问题
- 解决与HTTP 500 – 内部服务器错误错误信息有关的问题
- 从一个错误提示引出SQL中in和or的问题。
- 关于记录错误信息到文本文件的几点问题讨论
- [转]DW中出现 "以下翻译器没有被装载,由于错误:xxxx.htm:有不正确的设置信息" 问题的解决方案
- 解决文件无法上传的问题,错误信息:System.IO.DirectoryNotFoundException: Could not find a part of the path.
- 短期快速学习LINUX,涉及vi用法,管道,标准输入、输出和错误,grep 用法
- Linux 调用系统命令并截获标准输出(stdout)和错误输出(stderr)
- 解决Project Professional 2003连接Project Server 2003服务器"您没有权限以查看此页"错误信息的问题
- linux下播放音乐信息乱码问题
- "分析器错误信息: 未能加载类型“WebApplication1.Global”。"类似问题总结。
- 解决Linux系统安装后,root用户无法登录,提示“无法验证用户”的错误问题
- 如何在linux下查看tomcat的错误信息!
- Linux 下Tomcat运行一段时间报java.net.SocketException: Too many open files的错误问题解决
- 有关编译器错误信息: CS1595的补充问题 已在多处定义“CustomControls.FirstControl”
- 解决[ASP.NET]"编译器错误信息: CS1595: 已在多处定义"的问题
- 从错误信息思考一个问题:.NET Framework 与 COM/COM+ 到底有多深入的关联呢?
- 程序员最痛苦的事,就是程序出错;程序员最最痛苦的事,就是程序出错了还没有错误信息!--IIS Service Unavailable 问题如何解决