每天改变一点点,生活充满了惊喜。
全部博文(42)
分类: LINUX
2015-04-02 13:53:59
理解下面这些问题的重点需要了解Linux重定向的原理,网上很多,这里不做过多解释。
重点总结下在使用重定向过程中碰到的一些问题:
1. 1 >/dev/null 2>&1 和 2>&1 1>/dev/null
在写Shell脚本时,如果我们希望命令行执行时不打印任何的信息到终端,经常会在命令行后面加上 1>/dev/null 2>&1 以达到目的,
但是经常会写成 2>&1 1>/dev/null。
如果你理解了重定向的原理,就不难理解它们的差别:
文件描述符1和2分别为标准输出和标准错误,默认都输出到终端。
(注意:In Linux, everything is a file.终端是设备,在操作系统中对应于设备文件。)
1>/dev/null 2>&1
表示把标准输出重定向到/dev/null,再把标准错误重定向到文件描述符1所指向的文件(即/dev/null),最终标准输出和标准错误都输出到/dev/null 文件。
2>&1 1>/dev/null
表示把标准错误,重定向到1指向的文件(即终端),再把标准输出重定向到/dev/null,最终标准错误仍输出到终端,而标准输出输出到/dev/null。
2. sbin/nginx -V | grep --color "version" 失效
通过上面的命令行想看一下nginx的版本号,但grep失效了,输出了的还是./sbin/nginx -V原来的信息,
按照我的目的是只打印包含“version”这一行的信息,有些不能理解。
突然想到,管道只是透传标准输出,如果管道前的命令行是输出到标准错误了呢,改成以下的命令行:
$ ./sbin/nginx -V 2>&1 | grep --color "version"
nginx version: nginx/1.4.4
time这个命令有些特殊,它有两个命令,一般情况下,直接执行 time command,使用的是Shell的内建命令。
另外还有一个外部命令/usr/bin/time。它们的区别就不讲了,这里讲讲它们的重定向相关的问题:
如果我们执行 time echo 'test' >time.out,实际上不会成功,time的输出仍然打印到终端,这是因为命令最后的重定向是对echo起作用的。
这样我们就会有相应的解决办法:
{ time echo 'test'; } >time.out
加上花括号,明确表明命令行结构,这样上面的问题解决了,但还是依然如故,这次可以推测是重定向可能存在问题,试试:
{ time echo 'test'; } 2>time.out
成功了,原来time命令的输出是打印到标准错误的,为什么?
我的理解是,是为了不将time命令的输出和time命令要测试的命令行的输出打印到一起,例如上面的echo命令会打印到终端。
注意:上面的命令行,花括号两侧要有空格,花括号里的命令行结尾要有明确的命令行结束符分号。
(Shell的语法有时候就是这么的奇怪,实际上这和空格在Shell对命令行的解析时起到的重要作用有关系的。)
当然 (time echo 'test') 2>time.out 也是可行的,如果不了解花括号和圆括号的区别,希望你去详细学习下,这在Shell中是相当重要的概念。
以上圆满地解决了问题,再来看看/usr/bin/time命令,用上面的方法是可以解决的,
不过外部命令实验先功能比内建命令的一般要丰富些,它提供了选择项来完成重定向,
/usr/bin/time -o time.out echo 'test'
要变成追加输出到文件尾,类似于重定向中的 >>
/usr/bin/time -a -o time.out echo 'test'