Bash脚本中if条件里子shell与复合语句的差异探究
Bash中两种if条件写法的核心区别
先拆解两种写法的实际逻辑,核心差异来自运算符优先级和子shell的作用:
第一种写法:带括号的子shell执行
if ! ( cmd_A && cmd_B ); then doSth fi
- 括号
()会启动一个子shell,把cmd_A && cmd_B作为一个整体执行:- 先运行
cmd_A,如果成功(退出码0),再运行cmd_B;如果cmd_A失败,直接跳过cmd_B。 - 只有当
cmd_A和cmd_B都成功时,子shell的退出码是0;只要其中任意一步失败,子shell退出码非0。 !是对整个子shell的执行结果取反:如果子shell失败(任意命令失败),条件为真,执行doSth;如果子shell成功(两个命令都成),条件为假,不执行doSth。
- 先运行
- 额外影响:子shell里的环境变更(比如变量赋值、
cd切换目录)不会影响当前脚本的后续代码,因为子shell是独立的进程。
第二种写法:直接拼接的命令
if ! cmd_A && cmd_B; then doSth fi
- Bash里
!的优先级比&&高,所以实际逻辑等价于( ! cmd_A ) && cmd_B:- 先判断
cmd_A的结果:如果cmd_A失败,! cmd_A为真,才会继续执行cmd_B;如果cmd_A成功,! cmd_A为假,&&会短路,直接跳过cmd_B。 - 只有当
cmd_A失败并且cmd_B成功时,整个条件才为真,才会执行doSth;其他情况都不会进入doSth。
- 先判断
- 额外影响:所有命令都在当前shell执行,环境变更(比如变量、目录)会保留到后续代码中。
核心差异总结
- 逻辑判断完全不同:
- 第一种:只要
cmd_A或cmd_B任意一个失败,就执行doSth。 - 第二种:只有
cmd_A失败且cmd_B成功时,才执行doSth。
- 第一种:只要
- 环境影响不同:
- 第一种用子shell,内部环境变更不影响父脚本;第二种无分隔,环境变更会保留。
内容的提问来源于stack exchange,提问作者fluter
相关产品推荐
相关产品推荐

