set 命令的详解

set 命令常用设置

t命令的主要作用是设置SHELL的属性, 其语法为set [-abefhkmnptuvxBCEHPT] [-o option-name] [argument …] 或者 set [+abefhkmnptuvxBCEHPT] [+o option-name] [argument …],第一组与第二组都是set的选项,+号表示关闭选项,-号表示打开选项,最后一组argument是位置参数。顺便提一下,如果命令行下不带任何参数,直接运行set,会显示所有的环境变量和 Shell 函数。 各选项功能如下:

选项说明
-a标记修改的或者创建的变量为导出
-b立即通告任务终结。
-e如果一个命令以非零状态退出,则立即退出。
-f禁用文件名生成(模式匹配)。
-h当查询命令时记住它们的位置
-k所有的赋值参数被放在命令的环境中,而不仅仅是命令名称之前的参数。
-m启用任务控制。
-n读取命令但不执行
-o设定与选项名对应的变量:
-p无论何时当真实的有效的用户身份不匹配时打开。 禁用对 $ENV 文件的处理以及导入 shell 函数。关闭此选项会导致有效的用户编号和组编号设定为真实的用户编号和组编号
-t读取并执行一个命令之后退出。
-u替换时将为设定的变量当作错误对待。
-v读取 shell 输入行时将它们打印。
-x执行命令时打印它们以及参数。
-Bshell 将执行花括号扩展。
-C设定之后禁止以重定向输出的方式覆盖常规文件。
-E设定之后 ERR 陷阱会被 shell 函数继承。
-H启用 ! 风格的历史替换。当 shell 是交互式的时候这个标识位默认打 开。
-P设定之后类似 cd 的会改变当前目录的命令不追踪符号链接。
-T设定之后 DEBUG 陷阱会被 shell 函数继承。
任何剩余的参数会被赋值给位置参数。如果没有剩余的参数,位置参数不会被设置。
-任何剩余的参数会被赋值给位置参数。-x 和 -v 选项已关闭。

set -o 可以设置的参数如下

参数说明
allexport与 -a 相同
braceexpand与 -B 相同
emacs使用 emacs 风格的行编辑界面
errexit与 -e 相同
errtrace与 -E 相同
functrace与 -T 相同
hashall与 -h 相同
histexpand与 -H 相同
history启用命令历史
ignoreeofshell 读取文件结束符时不会退出
interactive-comments允许在交互式命令中显示注释
keyword与 -k 相同
monitor与 -m 相同
noclobber与 -C 相同
noexec与 -n 相同
noglob与 -f 相同
nolog目前可接受但是被忽略
notify与 -b 相同
nounset与 -u 相同
onecmd与 -t 相同
physical与 -P 相同
pipefail管道的返回值是最后一个非零返回值的命令的返回果,或者当所有命令都返回零是也为零。
posix改变默认时和 Posix 标准不同的 bash 行为以匹配标准
privileged与 -p 相同
verbose与 -v 相同
vi使用 vi 风格的行编辑界面
xtrace与 -x 相同

错误处理

一般情况下,每个Linux shell 执行完成后,都会返回一个结果,并将其保存到$?中,一般 0 表示执行成功,非 0 表示执行失败 。

$ set
$ echo $?
0

shell 脚本中一般会使用大量的命令,严格意义上,我们应该小心检查 每个关键命令的执行结果,以确定之后的执行逻辑。一般处理情况如下

#! /usr/bin/env bash
PID=`pidof abus-daemon `
RET=$?
if [ $RET -eq 0 ];then
  echo "dbus-daemon's pid is $PID"
else
  echo "dbus-daemon don't run"
fi
#  这里写错了进程名称,d写成了a,执行结果为
# dbus-daemon don't run

如果命令较少的话,这种写法可能还能被接受,如果shell脚本的规模比较大时,可想而知,如果都按照这种方式处理,整个脚本的代码结构会变得十分的丑陋,而且,如果我们忘记了检查命令返回值,可能会导致脚本程序执行紊乱,造成系统不安全。
-e选项就是解决这个问题的一种十分优雅的方案,-e表示如果一个命令以非零状态退出,则整个shell脚本程序就会立即退出。

#! /usr/bin/env bash

set -e
PID=`pidof abus-daemon `
echo "dbus-daemon's pid is $PID"

设置 set -e 的话,该脚本会退出,控制台没有信息显示,这显然不是我们想要的效果。 可以通过 set +e关闭 -e选项,通过set -e再次打卡-e选项。

#! /usr/bin/env bash

set +e
PID=`pidof abus-daemon `
echo "dbus-daemon's pid is $PID"
# 执行结果为
# dbus-daemon's pid is

-o errexit等同于-e选项。

变量未定义

shell脚本中,如果遇到未定义的变量,一般会按照空值来处理

#!/usr/bin/env bash
echo $NONE
echo "NONE not set"

由于 NONE 为空,继续向后执行,打印出下面的内容。这是不安全的,我们希望在遇到未定义的变量时,shell应该提示,并立即退出,-u选项可以完美的解决这个问题。

#!/usr/bin/env bash
set  -u
echo $NONE
echo "NONE not set"

# 执行结果为
# ./settestu.sh:行3: NONE:未绑定的变量

-o nounset等同于-u选项。

跟踪调试

在编写较大规模的shell脚本时,不可能一次就编写出正确的脚本,当出现bug时,我们可能希望可以看一下脚本的执行流程,-x选项可以打印当前执行的命令,方便调试、跟踪脚本的执行流程。

#! /usr/bin/env bash
set -x
ls set.sh
echo "ABC"
# 输出为 :
+ ls set.sh
set.sh
+ echo ABC
ABC

+号后面表示当前执行的命令,-o xtrace等同于-x选项。

管道

管道作为shell处理的终极武器,被人们经常用来处理复杂的业务处理,可以在一个管道命令序列中,只要最后的命令执行成功,整体的管道命令序列处理就会返回0,这使得我们不能跟踪管道中间命令的执行结果,这时-e选项就失去了作用,比如,

#! /usr/bin/env bash
set -e
cmd | echo "abc"
echo "efg"
#执行结果如下:
abc
./set.sh: 行 23: cmd:未找到命令
efg

可以看到,虽然cmd命令执行失败,但是"efg"依然打印了出来。所以,对于管道命令,set -e失去了约束,shell 提供-o pipefail选项来检测管道命令的执行状态,开启这个选项之后,只要管道中存在失败的命令,shell脚本就会立即退出。

#! /usr/bin/env bash
set -eo pipefail
cmd | echo "abc"
echo "efg"
#执行结果:
abc
./set.sh: 行 23: cmd:未找到命令

保存命令路径

hashall可以让Bash记录执行过的命令路径,并保存到一个内存的Hash表中,当再次执行相同命令时就不需要再通过PATH变量查找该命令的路径,这样可以提高效率。

$ set -h
$ hash
命中    命令
   2    /usr/bin/pidof
   1    /usr/bin/sudo
  14    /usr/bin/vim

但有时,程序的路径发生了变化,因为有Hash记录的存在反而会导致命令执行失败。
这时可以使用hash -d删除某个记录信息,或者使用hash -r清空整个Hash表,再或者使用set +h禁用hash表来解决这个问题。

$ hash -d  vim 
$ hash
命中    命令
   2    /usr/bin/pidof
   1    /usr/bin/sudo
$ hash  -r
$ hash
hash:哈希表为空
$ hash
命中    命令
   1    /usr/bin/vim
$ set  +h
$ hash
bash: hash: 已禁用哈希

脚本调试

set -x
打开脚本调试功能,也可以通过bash -x ***.sh打开
如果输出结果以双加号(++)开头则表示命令在子Shell中执行

检查语法

set -n
检查shell语法,但不会执行,等同于bash -n xxx.sh

设定与选项名对应的变量

set -o 可设定与选项名对应的变量,后直接添加参数与设定值即可,如

$ set -o
allexport       off
braceexpand     on
emacs           off
errexit         off
errtrace        off
functrace       off
hashall         off
histexpand      on
history         on
ignoreeof       off
interactive-comments    on
keyword         off
monitor         on
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              on
xtrace          on
$ set -o vi off
$ set -o
allexport       off
braceexpand     on
emacs           off
errexit         off
errtrace        off
functrace       off
hashall         off
histexpand      on
history         on
ignoreeof       off
interactive-comments    on
keyword         off
monitor         on
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              on
xtrace          off
$ set +o
set +o allexport
set -o braceexpand
set +o emacs
set +o errexit
set +o errtrace
set +o functrace
set +o hashall
set -o histexpand
set -o history
set +o ignoreeof
set -o interactive-comments
set +o keyword
set -o monitor
set +o noclobber
set +o noexec
set +o noglob
set +o nolog
set +o notify
set +o nounset
set +o onecmd
set +o physical
set +o pipefail
set +o posix
set +o privileged
set +o verbose
set -o vi
set +o xtrace

一般书写

经过上面的分析,相信大家已经了解了关于set的几个常用的选项以及它们的具体含义,它们是如此的重要,以至于在任何脚本的开头都要将它们添加上去,这样不但会提供脚本的编写、调试效率还能避免很多安全陷阱。一般的书写方式如下:

#! /usr/bin/env bash
set -eux
set -o pipefail
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle中的SET命令用于设置SQL*Plus环境变量和系统变量。以下是常用的SET命令及其详细解释: 1. SET AUTOCOMMIT ON/OFF:用于设置是否自动提交事务。当AUTOCOMMIT为ON时,每个SQL语句都会自动提交,而当AUTOCOMMIT为OFF时,需要手动提交。 2. SET DEFINE ON/OFF:用于设置是否开启变量替换。当DEFINE为ON时,SQL*Plus将会把变量替换为其值,而当DEFINE为OFF时,不会替换变量。 3. SET ECHO ON/OFF:用于设置是否显示SQL语句。当ECHO为ON时,SQL语句会显示在屏幕上,而当ECHO为OFF时,则不会显示。 4. SET FEEDBACK ON/OFF:用于设置是否显示操作结果。当FEEDBACK为ON时,SQL语句的操作结果会显示在屏幕上,而当FEEDBACK为OFF时,则不会显示。 5. SET HEADING ON/OFF:用于设置是否显示列标题。当HEADING为ON时,SQL语句的列标题会显示在屏幕上,而当HEADING为OFF时,则不会显示。 6. SET LINESIZE n:用于设置每行显示的字符数。n为一个整数,表示每行最多显示的字符数。 7. SET PAGESIZE n:用于设置每页显示的行数。n为一个整数,表示每页最多显示的行数。 8. SET SERVEROUTPUT ON/OFF:用于设置是否显示PL/SQL块的输出结果。当SERVEROUTPUT为ON时,PL/SQL块的输出结果会显示在屏幕上,而当SERVEROUTPUT为OFF时,则不会显示。 9. SET SQLPROMPT 'string':用于设置SQL*Plus的提示符。string为一个字符串,表示提示符的内容。 10. SET TERMOUT ON/OFF:用于设置是否输出结果到屏幕上。当TERMOUT为ON时,SQL语句的结果会输出到屏幕上,而当TERMOUT为OFF时,则不会输出结果。 以上是Oracle中常用的SET命令及其详细解释。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值