Alexander Mills Asked: 2020-01-24 17:52:23 +0800 CST2020-01-24 17:52:23 +0800 CST 2020-01-24 17:52:23 +0800 CST subshell 和 if 块之间的区别 772 有什么区别: set -e; ./create-git-tag.sh || { echo 'Could not create git tag.' exit 1; } 和 set -e; if ! ./create-git-tag.sh; then echo 'Could not create git tag.' exit 1; fi 我猜 if 块不会创建子shell,因此会在输入 if 块之前退出?它们似乎功能相同,行为有什么不同吗? bash shell 2 个回答 Voted Best Answer user391836 2020-01-24T19:18:19+08:002020-01-24T19:18:19+08:00 花括号{ }不会创建子壳,圆括号会: 重击(1) (清单) list 在子shell 环境中执行。 {列表;} list 只是在当前的 shell 环境中执行。 因此,无论是if语句还是... || { }表单都没有可能创建子外壳。 如果使用圆括号而不是大括号,则可以创建子外壳环境。如果第一个命令返回非零状态(即./create-git-tag.sh 失败)( ),OR 运算符将只允许到达此阶段。|| 如果set -e使用,所有形式都表现出相同的行为(在测试命令失败时,shell 立即退出)——但在幕后,圆括号将创建一个子 shell(这在本示例中似乎没有用)。 如果set -e 不使用,创建一个子shell( )意味着子shell 将退出,但调用shell 将继续——随后的命令仍将被执行。 在所有情况下,只有在测试命令失败时才会输入 echo-exit 命令链(以及圆括号的相关子 shell)。但是制作条件逻辑的目的是某些事情可能会失败,也可能不会——这就是你在问题中的措辞没有意义的地方: 我猜 if 块不会创建子shell,因此会在输入 if 块之前退出? if 块是“进入”的,它运行测试命令来确定接下来要做什么。 就个人而言,我发现该if语句更易于阅读,并且更喜欢在脚本中使用它。当我以“交互方式”使用 shell 时,操作员&&和||我可能会在's 的地方使用。if Andy Dalton 2020-01-24T19:12:47+08:002020-01-24T19:12:47+08:00 我的理解是它们是等价的。在这两种情况下,exit都会终止运行脚本的 shell 实例。 您所拥有的任何一个版本都不会创建子shell。为了证明这一点,请考虑以下实验: $ cat version1 #!/bin/bash set -e x=7 ls /tmp/does/not/exist &> /dev/null || { x=42 } echo $x $ ./version1 42 $ cat version2 #!/bin/bash set -e x=7 if [ ! ls /tmp/does/not/exist &> /dev/null ]; then x=42 fi echo $x $ ./version2 42 如果将{ }in更改version1为()(如以下版本中所示),则会创建一个子 shell。因此,对xwithin 的修改( )不会影响x调用 shell: $ cat version3 #!/bin/bash set -e x=7 ls /tmp/does/not/exist 2> /dev/null || ( x=42 ) echo $x $ ./version3 7
花括号
{ }
不会创建子壳,圆括号会:因此,无论是
if
语句还是... || { }
表单都没有可能创建子外壳。如果使用圆括号而不是大括号,则可以创建子外壳环境。如果第一个命令返回非零状态(即./create-git-tag.sh 失败)
( )
,OR 运算符将只允许到达此阶段。||
如果
set -e
使用,所有形式都表现出相同的行为(在测试命令失败时,shell 立即退出)——但在幕后,圆括号将创建一个子 shell(这在本示例中似乎没有用)。如果
set -e
不使用,创建一个子shell( )
意味着子shell 将退出,但调用shell 将继续——随后的命令仍将被执行。在所有情况下,只有在测试命令失败时才会输入 echo-exit 命令链(以及圆括号的相关子 shell)。但是制作条件逻辑的目的是某些事情可能会失败,也可能不会——这就是你在问题中的措辞没有意义的地方:
if 块是“进入”的,它运行测试命令来确定接下来要做什么。
就个人而言,我发现该
if
语句更易于阅读,并且更喜欢在脚本中使用它。当我以“交互方式”使用 shell 时,操作员&&
和||
我可能会在's 的地方使用。if
我的理解是它们是等价的。在这两种情况下,
exit
都会终止运行脚本的 shell 实例。您所拥有的任何一个版本都不会创建子shell。为了证明这一点,请考虑以下实验:
如果将
{ }
in更改version1
为()
(如以下版本中所示),则会创建一个子 shell。因此,对x
within 的修改( )
不会影响x
调用 shell: