碰到问题
在自己编写的一个小脚本中,碰到这个一个小问题:
问题背景:
在脚本中多次导出数据,为了不用重复输入密码,在运行时,使用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),如下:
数据流重导向和管道
当然,我们可以使用 2>&1 的数据流重定向,将错误输出(stderr)导向标准输出,这里很多人都知道:
如果这时又要将输出信息导出到文件的话,我们能从很多博客或者教材中看到这样的写法:
然而,这样的话,标准输出(stdout)和错误输出(stderr)都到一起了,如果我们要将两个输出分开到两个文件存放(对!人生苦短,就是要这么钻牛角尖和丧心病狂)。
用这个来模拟问题就是:标准输出(stdout)导出到/tmp/aa文件,错误信息(stderr)中只留下”fff“文件的这条,其他的过滤
问题解决方法
这样其实也很容易,具体的方法就是:将”1>/tmp/aa“和”2>&1“位置对调下!

这样,正确信息导出到/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
如果有人知道具体怎么解释,或者有管道这方面的资料的话,欢迎告诉我

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/170554.html