Linux(Centos 7.6)命令详解:set

1.命令作用

设置shell的属性变量,显示当前shell所有变量(包括shell变量、自定义变量、用户变量) 

2.命令语法

Usage: set [+/-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]

3.参数详解

OPTION:

  • -a,启用‌自动导出模式‌,此后所有新建或修改的变量会自动标记为环境变量(等效于 export VAR)
  • +a,关闭自动导出模式,恢复默认行为(需手动export导出变量)
  • -b,后台执行结果执行完直接输出
  • +b,后台执行结果执行完需要等待回车或者下一个命令执行才输出(默认)
  • -e,脚本运行错误时直接退出
  • +e,脚本运行错误会接着后续的程序运行,直到脚本运行完(默认)
  • -f/+f,关闭/启动文件名称通配符匹配
  • -h/+h,记录函数存储路径,避免重复查找加速后续调用,大型脚本推荐使用以提升性能
  • -k/+k,开启参数转环境变量功能
  • -m/+m,启用/关闭作业控制的选项
  • -n/+n,启动/关闭语法检测,启动参数则不会实际执行命令,关闭参数则实际执行命令
  • -p/+p,启动优先顺序模式‌,shell会以更高优先级执行命令,可能影响系统资源分配
  • -t,执行后退出shell
  • -u/+u,启动/关闭未定义变量检查选项
  • -v/+v,启动/关闭详细模式,启动会在执行时‌逐行显示原始的命令‌
  • -x/+x,启动/关闭调试模式,启动会在执行时‌逐行显示执行的命令
  • -B/+B,启动/关闭大括号扩展匹配
  • -C/+C,关闭/启动重定向覆盖文件‌,启用>重定向,若目标文件已存在则报错,需使用>|强制覆盖,关闭则使用默认的>重定向
  • -H/+H,启用/关闭历史命令扩展匹配,允许通过 ! 符号快速调用或修改历史记录中的命令
  • -P/+P,启用/关闭物理路径模式‌
  • -o/+o,查看或设置shell选项‌

4.常用用例

4.1.启用‌自动导出模式‌(设置的变量是环境变量)

[root@node2 ~]# env | grep DB_HOST          # 查看没有DB_HOST环境变量
[root@node2 ~]# DB_HOST="localhost"         # 设置DB_HOST变量(这里是普通的变量,设置后env里面看不到)
[root@node2 ~]# env | grep DB_HOST          # 查看没有DB_HOST用户变量
[root@node2 ~]# set -a
[root@node2 ~]# DB_HOST="localhost" 
[root@node2 ~]# env | grep DB_HOST          # 在set -a后设置DB_HOST变量是环境变量,env里面可以看到,与export DB_HOST="localhost" 效果一样
DB_HOST=localhost
[root@node2 ~]# set +a                      # 关闭后恢复默认,设置的变量是普通变量
[root@node2 ~]# env | grep DB_HOST
DB_HOST=localhost
[root@node2 ~]# 

4.2.控制后台命令执行输出效果

[root@node1 ~]# set -b
[root@node1 ~]# sleep 5 &          # 指定set -b后,后台执行完后直接输出结果
[1] 33954
[root@node1 ~]# [1]+  Done                    sleep 5

[root@node1 ~]# set +b             # 指定set +b后,后台执行完后需要回车或者执行下一个命令才输出执行结果(默认效果)
[root@node1 ~]# sleep 5 &
[1] 33955
[root@node1 ~]# 
[1]+  Done                    sleep 5
[root@node1 ~]# 

4.3.shell脚本开启错误直接退出

[root@node1 ~]# cat test.sh 
#!/bin/bash  
set -e                        # 开启错误退出  
mkdir /tmp/example/dir1       # 如果/tmp/example不存在,则创建该目录会失败
cd /tmp/example/dir1
echo "execution is completed"  
set +e                        # 关闭错误退出
[root@node1 ~]# sh test.sh    # 执行到创建目录失败就直接退出,不会输出execution is completed
mkdir: cannot create directory ‘/tmp/example/dir1’: No such file or directory
[root@node1 ~]# 

4.4.关闭文件名通配符

[root@node1 ~]# set -f        # 关闭文件名通配符扩展,*txt会当成普通字符
[root@node1 ~]# echo *txt
*txt
[root@node1 ~]# set +f        # 开启文件名通配符扩展,*txt通配匹配所有txt结尾的文件
[root@node1 ~]# echo *txt
test.txt
[root@node1 ~]# 

4.5.启停作业控制的选项

# 命令解释:
sleep 100 &  # 任务1 后台运行
sleep 120 &  # 任务2 后台运行
jobs         # 查看任务编号(如 [1], [2])
fg %2        # 将任务2 提到前台,可以执行Ctrl+Z暂停前台任务并保留到后台
bg %2        # 将暂停的任务转为后台运行
kill %2      # 终止指定编号的后台任务

# 测试用例:
[root@node1 ~]# set -m          # 默认,启动管理jobs后台任务
[root@node1 ~]# sleep 100 &
[1] 37813
[root@node1 ~]# sleep 120 &
[2] 37814
[root@node1 ~]# jobs
[1]-  Running                 sleep 100 &
[2]+  Running                 sleep 120 &
[root@node1 ~]# fg %2
sleep 120
^Z
[2]+  Stopped                 sleep 120
[root@node1 ~]# jobs
[1]-  Running                 sleep 100 &
[2]+  Stopped                 sleep 120
[root@node1 ~]# bg %2
[2]+ sleep 120 &
[root@node1 ~]# jobs
[1]-  Running                 sleep 100 &
[2]+  Running                 sleep 120 &
[root@node1 ~]# kill %2
[root@node1 ~]# jobs
[1]-  Running                 sleep 100 &
[2]+  Terminated              sleep 120
[root@node1 ~]# jobs
[1]+  Running                 sleep 100 &
[root@node1 ~]# 

[root@node1 ~]# set +m           # 关闭jobs后台任务的管理
[root@node1 ~]# sleep 100 &
[1] 37849
[root@node1 ~]# sleep 120 &
[2] 37850
[root@node1 ~]# jobs
[1]-  Running                 sleep 100 &
[2]+  Running                 sleep 120 &
[root@node1 ~]# fg %2            # 设置set +m后,后台任务管理会报错
-bash: fg: no job control
[root@node1 ~]# 

4.6.启动语法检测并不实际执行

[root@node1 ~]# cat test1.sh 
#!/bin/bash  
set -n                                  # 启动语法检测,读取脚本命令并检查语法错误,但‌不执行任何实际命令 
mkdir -p /tmp/example/dir1   
cd /tmp/example/dir1
echo "execution is completed"  
set +n                                  # 关闭语法检测,关闭后执行就是实际执行
[root@node1 ~]# sh test1.sh             # 其中有-n参数,所以实际并不执行任何命令
[root@node1 ~]# ll /tmp/example/dir1    # 实际并不执行,所以目录不存在
ls: cannot access /tmp/example/dir1: No such file or directory
[root@node1 ~]# 

4.7.对未定义变量进行检查

[root@node1 ~]# echo $UNDEFINED_VAR

[root@node1 ~]# set -u
[root@node1 ~]# echo $UNDEFINED_VAR
-bash: UNDEFINED_VAR: unbound variable
[root@node1 ~]# 

 4.8.启动详细模式

[root@node1 ~]# cat test2.sh 
#!/bin/bash  
set -v
name="zhangsan"  
echo "Hello, $name"
set +v
[root@node1 ~]# sh test2.sh 
name="zhangsan"  
echo "Hello, $name"
Hello, zhangsan
set +v
[root@node1 ~]#

4.9.启动调试模式

[root@node1 ~]# cat test3.sh 
#!/bin/bash  
set -x
name="zhangsan"  
echo "Hello, $name"
set +x
[root@node1 ~]# sh test3.sh 
+ name=zhangsan
+ echo 'Hello, zhangsan'
Hello, zhangsan
+ set +x
[root@node1 ~]# 

4.10.启停大括号扩展匹配 

[root@node1 ~]# set -B                  # 启用大括号扩展匹配
[root@node1 ~]# echo file_{A,B,C}.txt 
file_A.txt file_B.txt file_C.txt
[root@node1 ~]# echo {1..3}-item 
1-item 2-item 3-item
[root@node1 ~]# 
[root@node1 ~]# set +B                  # 关闭大括号扩展匹配
[root@node1 ~]# echo file_{A,B,C}.txt 
file_{A,B,C}.txt
[root@node1 ~]# echo {1..3}-item 
{1..3}-item
[root@node1 ~]# 

 4.11.启停重定向覆盖文件

[root@node1 ~]# set -C
[root@node1 ~]# echo 'This is new content' > exist.txt
[root@node1 ~]# echo 'This is new content' > exist.txt
-bash: exist.txt: cannot overwrite existing file
[root@node1 ~]# echo 'This is new content' >| exist.txt
[root@node1 ~]# set +C
[root@node1 ~]# echo 'This is new content' > exist.txt
[root@node1 ~]# 

4.12.启停历史命令扩展匹配

# 执行history中的历史命令
[root@node1 ~]# history | grep 1026
 1026  ll test.sh 
 1047  history | grep 1026
[root@node1 ~]# !1026               # 执行history中id为1026的命令
ll test.sh 
-rw-r--r--. 1 root root 187 Jun 11 18:22 test.sh
[root@node1 ~]# !!                  # 执行上一个命令,即history中最后一个命令
ll test.sh 
-rw-r--r--. 1 root root 187 Jun 11 18:22 test.sh
[root@node1 ~]# !ll                 # 执行最后一个带有ll的参数
ll test.sh 
-rw-r--r--. 1 root root 187 Jun 11 18:22 test.sh
[root@node1 ~]# 

# 启停历史命令扩展匹配
[root@node1 ~]# set -H
[root@node1 ~]# ll test.sh test1.sh
-rwxr-xr-x. 1 root root 190 Jun 11 20:36 test1.sh
-rw-r--r--. 1 root root 187 Jun 11 18:22 test.sh
[root@node1 ~]# chmod 755 !$
chmod 755 test1.sh
[root@node1 ~]# set +H
[root@node1 ~]# ll test.sh test1.sh
-rwxr-xr-x. 1 root root 190 Jun 11 20:36 test1.sh
-rw-r--r--. 1 root root 187 Jun 11 18:22 test.sh
[root@node1 ~]# chmod 755 !$
chmod: cannot access ‘!$’: No such file or directory
[root@node1 ~]# 

说明:
!^,读取上一个命令第一个参数值,ll是命令,第一个参数是test.txt
!$,读取上一个命令最后一个参数值,ll是命令,第二个参数是test1.txt
!:2,读取上一个命令第二个参数值
!:0,是命令名,命令参数是从1开始

4.13.启停物理路径模式

set -P  # 启用物理路径模式  
cp /opt/link_to_config /backup/  # 复制实际文件而非符号链接

set +P  # 关闭物理路径模式  
ls /usr/bin/python*  # 快速读取缓存路径,加速重复命令

‌4.14.查看或设置shell选项‌

set -o            # 列出所有shell选项及其开关状态,on为启用,off为关闭
set -o 选项名     # 启用选项  
set +o 选项名     # 关闭选项 

4.15.其他

set -o errexit        # 同set -e,命令失败时退出
set -o nounset        # 同set -u,未定义变量时报错
set -o xtrace         # 同set -x,启动调试模式
set -o pipefail       # 管道错误检测

[root@node1 ~]# set -o pipefail  # 启动后,管道符前后所有命令必须都成功才算成功
[root@node1 ~]# true | true
[root@node1 ~]# echo $?
0
[root@node1 ~]# false | true
[root@node1 ~]# echo $?
1
[root@node1 ~]# true | false
[root@node1 ~]# echo $?
1
[root@node1 ~]# false | false
[root@node1 ~]# echo $?
1
[root@node1 ~]# 
[root@node1 ~]# 
[root@node1 ~]# set +o pipefail   # 未启动时,仅管道符最后一个命令成功才算成功(默认参数)
[root@node1 ~]# true | true
[root@node1 ~]# echo $?
0
[root@node1 ~]# false | true
[root@node1 ~]# echo $?
0
[root@node1 ~]# true | false
[root@node1 ~]# echo $?
1
[root@node1 ~]# false | false
[root@node1 ~]# echo $?
1
[root@node1 ~]# 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆是浪个

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值