wangbin
  • wangbin
  • 2019-11-16
  • IT

shell标准错误输出:2>&1

一. 简介

写shell脚本的时候,如果不想控制台打印命令的输出时,会在命令后面加上>/dev/null 2>&1,例如echo "111" >/dev/null 2>&1.

>/dev/null很好理解,将输出写入空设备文件,就不会显示在控制台上了,那2>&1是什么意思,它还有哪些其他的用法呢?

二.初识2>&1

首先说下,shell有两种输出,标准输出stdout和标准错误输出stderr。

stdout很好理解,echo "111",控制台显示"111",这个就是stdout。

那什么是stderr呢?这里说下我和它的初识。

最近写jenkins打包打包脚本接到个需求,如果git pull代码的时候出错,则停止打包。看了下pull失败会提示"fatal:could not read Username",那好办了,按照我之前处理的方式,将$(git pull)执行的结果赋值RESULT_STRING,如果它包含"fatal:could not read Username",则exit 1就好了。

结果echo ${RESULT_STRING}一直没显示"fatal:could not read Username",百思不得其解,后来突然想到了之前不显示所有输出>/dev/null 2>&1这个写法,依稀记得说是有部分输出不一样,需要加上2>&1,才能让所有的输出都不显示在控制台。

那看到这儿,你可能已经认识到了,git pull报错的提示,就是标准错误输出stderr。

说来惭愧,之前还吐槽一阵子,git这么有名的工具,怎么犯这种错误,输出都不好拿到,现在想来,它做的才是最正宗的,错误提示当然要用标准错误输出呀。

总结下来,shell有两种输出,标准输出stdout和标准错误输出stderr。

  1. echo "111",控制台显示"111",这个是标准输出stdout,shell文件描述符1,当然默认的输出就是它
  2. git pull失败,jenkins鱼腥显示"fatal:could not read Username",是标准错误输出stderr,shell文件描述符2
  3. 既然有1和2了,那么0呢?是stdin,标准输入,也可以说是键盘输入

三. 深究2>&1

既然知道有两种输出,那么>/dev/null 2>&1是如何将这两种输出都不显示出来的呢?

先说>/dev/null,相当于1>/dev/null,>是重定向的意思,例如echo "111" > /tmp/1.txt,将"111"重定向,也就是写入/tmp/1.txt文件中,会覆盖之前的内容,执行后1.txt中只存在"111"。对应的echo "111" >> /tmp/1.txt是追加到1.txt文件后面。

2>&1中,&是等同于的意思,2标准错误输出等同于1标准输出,则将标准错误输出也输出到标准输出上,而前面1>/dev/null,则全部都不会显示到控制台。

四. 使用2>&1实现git pull失败停止的功能

好了,知道了上面的原理,我们可以将标准错误输出到单独文件,然后再读取它,就可以解决我们的问题了,下面是代码

TMP_LOG_PATH="/tmp/tmp-git.log"
git pull 2>${TMP_LOG_PATH}
RESULT_STRING=$(cat ${TMP_LOG_PATH})
if [[ ${RESULT_STRING} =~ "fatal:" ]] \
   || [[ ${RESULT_STRING} =~ "error:" ]]; then
    exit 1
fi

五:svn up失败则停止任务

类似的,代码如下

TMP_LOG_PATH="/tmp/tmp-svn.log"
svn up 2>${TMP_LOG_PATH}
RESULT_STRING=$(cat ${TMP_LOG_PATH})
if [[ ${RESULT_STRING} =~ "svn:E" ]]; then
    exit 1
fi

六. 将脚本所有输出保存到文件

我们写定时脚本的时候,想将脚本执行的所有输出到一个文件,然后邮件发送到我们邮箱。

这时候如果每执行个命令后面都加上 > /tmp/xxx.log,当然也是可以实现的,但是有没有更优雅的做法呢?

当然有的,可以在脚本中执行下面命令就可以啦

LOG_PATH=/vps/save/logs/crontab/day-hour0.log
touch ${LOG_PATH}
exec 1>> ${LOG_PATH}

具体为啥,也比较复杂,后面有空再说。

七. 总结

shell处处都是坑呀,不清楚各种使用的,遇到个需求都要磕半天,有空还是要多了解下。

参考:

  1. https://www.cnblogs.com/ultranms/p/9353157.html

  2. https://blog.csdn.net/heimao0307/article/details/79498206