linux中的set命令: "set -e" 与 "set -o pipefail"

转载 2016年06月02日 11:05:42
工作中经常在shell脚本中看到set的这两个用法,但就像生活中的很多事情,习惯导致忽视,直到出现问题才引起关注。

1. set -e
set命令的-e参数,linux自带的说明如下:
"Exit immediately if a simple command exits with a non-zero status."
也就是说,在"set -e"之后出现的代码,一旦出现了返回值非零,整个脚本就会立即退出。有的人喜欢使用这个参数,是出于保证代码安全性的考虑。但有的时候,这种美好的初衷,也会导致严重的问题。

真实案例:
脚本a.sh开头使用了"set -e",且能正常运行。在几个月或更久以后,因需求升级,在脚本中增加了3行hadoop操作:
#!/bin/bash
set -e
...
/home/work/.../hadoop dfs -rmr /app/.../dir
/home/work/.../hadoop dfs -mkdir /app/.../dir
/home/work/.../hadoop dfs -put file_1 /app/.../dir/
...
这几行hadoop命令逻辑很简单:在hdfs上清除并新建一个目录,并将一份本地文件推送至这个目录,供后续使用。将这几行单拎出来,在命令行下执行,除了提示待删除的目录不存在,并没有什么问题,文件还是会被推送到指定的地方。

但第一次执行这个脚本的时候,却失败退出了,且导致调用该脚本的程序整体退出,造成了严重的后果。原因是hdfs上还没有这个目录,rmr这一行会返回255,这个值被脚本前方的"set -e"捕捉到,直接导致了脚本退出。

新增的代码本身并没有问题,先删除再新建目录,反而是保证数据安全的比较规范的操作,删除命令本身的容错性,可以保证后续命令正常执行。事实是这个脚本有好几百行,且逻辑比较复杂,在增加这几行代码的时候,开发人员已经不记得这个脚本里还有个"set -e"埋伏着了。

可见设置"set -e",在脚本开发过程中可能很有帮助,而在开发完成后,特别是对于后期可能有升级的脚本,则可能是埋下了安全隐患。

2. set -o pipefail
对于set命令-o参数的pipefail选项,linux是这样解释的:
"If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a  non-zero  status,or zero if all commands in the pipeline exit successfully.  This option is disabled by default."

设置了这个选项以后,包含管道命令的语句的返回值,会变成最后一个返回非零的管道命令的返回值。听起来比较绕,其实也很简单:

# test.sh
set -o pipefail
ls ./a.txt |echo "hi" >/dev/null
echo $?

运行test.sh,因为当前目录并不存在a.txt文件,输出:
ls: ./a.txt: No such file or directory
 # 设置set -o pipefail,返回从右往左第一个非零返回值,即ls的返回值1

注释掉set -o pipefail 这一行,再次运行,输出:
ls: ./
a.txt: No such file or directory
 # 没有
set -o pipefail,
默认返回最后一个管道命令的返回值

相关文章推荐

Flume学习12_Flume Spooling directory source读取文件格式的要求

把Flume的Source设置为 Spooling directory source,在设定的目录下放置需要读取的文件,一些文件在读取过程中会报错。 文件格式和报错如下: 实验一 读取汉子和...

flume上报日志到kafka

1.flume安装 参考:http://blog.csdn.net/lnho2015/article/details/52035145 1. 系统需求 Flume需要Java 1.6及以上(推荐1.7...

排序之冒泡排序

冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大...

声纹识别之PLDA算法描述

之前我写过《我对说话人识别/声纹识别的研究综述》,本篇基本上可以是这个综述的续写。其实,写的也没有什么深度,想获得深度信息的朋友们可以不用往下看了,还不如下载几篇领域内的国内博士论文看看。为什么是国内...

Unix/Linux 脚本中 “set -e” 的作用

----------------------------------------------------------- #!/bin/bash set -e command 1 command 2...

基于霍夫曼编码的任意文件压缩程序

本程序主要使用霍夫曼编码对任意文件进行压缩。 程序的步骤如下: 如果有一个文件大小为8个bytes。 其中ascii为m的字符一共出现了n次: m      n 1       3 2      ...

ffmpeg分解视频文件并加密

ffmpeg,可以将视频分解成小块,并根据密钥进行内容加密。首先需要将密钥写入文件video.key。还需要第二个文件,key_info来存储是关键信息文件。它具有以下格式:key URI key f...
  • cnhome
  • cnhome
  • 2017-06-14 17:31
  • 1179

跟我一起写 Makefile(五)

六、多目标Makefile的规则中的目标可以不止一个,其支持多目标,有可能我们的多个目标同时依赖于一个文件,并且其生成的命令大体类似。于是我们就能把其合并起来。当然,多个目标的生成规则的执行命令是同一...
  • haoel
  • haoel
  • 2004-02-24 16:50
  • 52681

跟我一起写 Makefile(七)

使用变量————在Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。其与C/C++所不同的是,你...
  • haoel
  • haoel
  • 2004-02-25 10:15
  • 23661

跟我一起写 Makefile(六)

书写命令————每条规则中的命令和操作系统Shell的命令行是一致的。make会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非,命令是紧跟在依赖规则后面的分号后的。在命令行之间...
  • haoel
  • haoel
  • 2004-02-24 16:51
  • 42963
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)