加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

set是Linux系统中用来设置shell的命令

发布时间:2023-10-31 10:06:45 所属栏目:Linux 来源:转载
导读:   set是Linux系统中用来设置shell的命令,它能设置所使用shell的执行方式,可依照不同的需求来做设置。 set命令的参数,linux自带的说明如下:



  参数说明:



  -a  标示
  set是Linux系统中用来设置shell的命令,它能设置所使用shell的执行方式,可依照不同的需求来做设置。 set命令的参数,linux自带的说明如下:
 
  参数说明:
 
  -a  标示已修改的变量,以供输出至环境变量。
 
  -b  使被中止的后台程序立刻回报执行状态。
 
  -C  转向所产生的文件无法覆盖已存在的文件。
 
  -d  Shell预设会用杂凑表记忆使用过的指令,以加速指令的执行。使用-d参数可取消。
 
  -e  若指令传回值不等于0,则立即退出shell。
 
  -f   取消使用通配符。
 
  -h  自动记录函数的所在位置。
 
  -H Shell  可利用”!”加的方式来执行history中记录的指令。
 
  -k  指令所给的参数都会被视为此指令的环境变量。
 
  -l  记录for循环的变量名称。
 
  -m  使用监视模式。
 
  -n  只读取指令,而不实际执行。
 
  -p  启动优先顺序模式。
 
  -P  启动-P参数后,执行指令时,会以实际的文件或目录来取代符号连接。
 
  -t  执行完随后的指令,即退出shell。
 
  -u  当执行时使用到未定义过的变量,则显示错误信息。
 
  -v  显示shell所读取的输入值。
 
  -x  执行指令后,会先显示该指令及所下的参数。
 
  +  取消某个set曾启动的参数。
 
  也就是说,在”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/
  
   ...123456
  
  这几行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 $?123
  
  运行test.sh,因为当前目录并不存在a.txt文件,输出: ls: ./a.txt: No such file or directory 1 #设置了set -o pipefail,返回从右往左第一个非零返回值,即ls的返回值1
 
  注释掉set -o pipefail这一行,再次运行,输出: ls: ./a.txt: No such file or directory 0 # 没有set -o pipefail,默认返回最后一个管道命令的返回值
 

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章