0%

浅谈Shell命令的组合

这里介绍Shell常用的命令连接、分组方式

abstract.png

命令连接

分号 ;

依次执行所有命令,无论前面的命令执行结果是成功还是失败

1
2
3
4
5
# 依次执行下述命令
ls -l ; date ; cat main.java

# 依次执行下述命令
ls -l ; cat StuServiceImpl.java ; cat main.java

figure 1.png

逻辑与 &&

只有在前一个命令执行成功后,才会执行下一个命令。与Java中短路求值机制很类似

1
2
3
4
5
# 只有在前一个命令执行成功后,才会执行下一个命令
ls -l && date && cat main.java

# 只有在前一个命令执行成功后,才会执行下一个命令
ls -l && cat StuServiceImpl.java && cat main.java

figure 2.png

逻辑或 ||

前一个命令执行成功,则后面的命令不会执行;只有在前一个命令执行失败后,才会执行下一个命令。与Java中短路求值机制很类似

1
2
3
4
5
# 只有在前一个命令执行失败后,才会执行下一个命令
ls -al || date || cat main.java

# 只有在前一个命令执行失败后,才会执行下一个命令
cat readme.txt || cat service.java || date || cat main.java

figure 3.png

命令分组

语法

使用()分组时其会创建子shell,使得括号中的每个命令都在该子shell中执行。由于命令是在子shell中执行的,因此在子shell完成后变量分配不会影响父shell。语法规则如下,(左括号的后面、)右括号的前面必须要有一个空格。括号中的最后一个命令后面的分号不是必须的

1
2
3
4
( date ; ls -ld ; cat main.java ; )

# 命令列表中的最后一个命令后的分号可以没有
( date ; ls -ld ; cat main.java )

figure 4.png

使用{}分组时,括号的每个命令都会在当前shell中执行,不会创建子shell。语法规则如下,{左括号的后面、}右括号的前面必须要有一个空格。同时,括号中的最后一个命令后的分号必须要有

1
2
# 命令列表中的最后一个命令后的分号必须要有
{ date ; ls -ld ; cat main.java ; }

figure 5.png

区别

这里我们使用的Shell为zsh,故可通过ZSH_SUBSHELL变量的值判断当前shell是否为子shell。该变量值为0时,表示该shell不是子shell;该变量值如果比0大,则表明是子shell。该值可以表示当前子shell的嵌套级别。例如,父shell的值是0,子shell的值为1,子shell的子shell值是2,以此类推。同时,由于cd命令切换目录时会设置环境变量PWD,而pwd命令则通过读取环境变量PWD获取当前路径信息。至此,我们就可以验证两种分组方式的影响、区别

1
2
3
4
5
# 使用()分组
( echo "sub shell: $ZSH_SUBSHELL" ; cd ./Downloads/Demo1 ; pwd ; echo "sub shell: $ZSH_SUBSHELL" ; )

# 使用{}分组
{ echo "sub shell: $ZSH_SUBSHELL" ; cd ./Downloads/Demo1 ; pwd ; echo "sub shell: $ZSH_SUBSHELL" ; }

figure 6.png

通过ZSH_SUBSHELL变量的值可以证明()分组中的命令是在子shell当中执行的;同时,在子shell中的更改操作(例如,对变量值进行修改),一旦子shell结束后,所有更改都会消失。故通过()分组执行完毕后,不会修改当前路径;而通过{}分组执行完毕后,当前路径则会被更新

场景

常见的使用命令分组的场景有:

1. 多条命令的输出需要重定向到同一个文件

1
2
3
4
5
6
# 分别重定向
who am I >> a.txt
date >> a.txt

# 使用命令分组进行统一重定向
{ who am I ; date ; } >> b.txt

figure 7.png

2. 对多条命令整体进行有条件连接

1
2
# 如果b.txt文件不存在,则创建、写入该文件
ls -l b.txt || { echo "this is b file" >> b.txt; cat b.txt ; }

figure 8.png

参考文献

  1. Linux命令行与shell脚本编程大全·第4版 Richard Blum、Christine Bresnahan著
请我喝杯咖啡捏~

欢迎关注我的微信公众号:青灯抽丝