平时在写shell,或者配置dockerfile等用到shell脚本的时候,常常用到一些习惯用法,大概知道什么意思,也能用对,但就是不能理解为什么这样用,那么就没办法变通。今天分享一个习惯用法,io重定向里面一个比较常用的写法:ls foo > /dev/null 2>&1
这个碰到最多的是crontab配置,尝尝会把1,2都同时重定向到一个文件中。

I/O重定向

标准输出例子

$ cat foo.txt
foo
bar
baz

重定向例子

$ cat foo.txt > output.txt
$ cat output.txt
foo
bar
baz

以上例子,标准输出就默认打印到屏幕上。重定向后默认不打印到屏幕,而是将内容保存到文件output.txt中。
所以重定向就是将输出重定向到其他地方。

$ cat nop.txt > output.txt
cat: nop.txt: No such file or directory

如果cat的是一个不存在的文件还是会报错,这就牵涉到标准错误,标准输出了。

标准输出和标准错误

我们在shell中运行程序都会同时打开标准错误2、标准输出1,分别对应标号1和2。标准输出就代表程序的正常输出,默认会打印到屏幕。标准错误代表程序的错误,默认也会打印到屏幕。
所以默认重定向是将标准输出重定向,像nop.txt不存在这种出现的提示输入标准错误,可以这样 cat nop.txt 2> output.txt 就不会显示出来错误了。

&取文件标识

everything is a file
&是代表取文件的标识,那么开篇提到的&1,就代表标准输出的文件标识符。

最终结论

结合&和重定向,2 > &1, 代表将标准错误重定向到标准输出,那么当我们想将两者都保存的时候就可以ls foo > /filepath.log 2>&1, 即将标准输出冲顶到filepath.log文件中,同时将标准错误也记录到标准输出中,也就是都保存到filepath.log中。
如果不用这种写法,那么就要稍微麻烦一点:

ls foo > /filepath.log 2 > /filepath.log

https://www.brianstorti.com/understanding-shell-script-idiom-redirect/