/bin/sh 中逻辑表达式链的评估
evaluation of logical expression chain in /bin/sh
我无法理解此 posix shell 代码的工作原理。
my_dir=/tmp/foo_dir
[ -d $my_dir ] || mkdir -p $my_dir || echo "Error creating '$my_dir'!"
考虑目录不存在的情况。
-d returns 如果目录不存在则为零,因此会评估 "mkdir"。
mkdir returns 成功后为零,这应该导致 "echo" 也被评估。但是此代码有效(echo
仅在通过将 my_dir
更改为 /ttmp/foo_dir"
导致目录创建失败时打印)
在posixshell中,0表示成功,其他值表示失败。当我们在逻辑表达式中使用命令时,我们正在测试它的退出状态。我们可以使用 $?
来检查最后的退出状态。
正在试验:
$ true
$ echo $?
0
$ false
$ echo $?
1
$ [ -d tmpdir ]
$ echo $?
1
$ mkdir tmpdir
$ echo $?
0
$ mkdir tmpdir
mkdir: tmpdir: File exists
$ echo $?
1
$ mkdir -p tmpdir
$ echo $?
0
$ [ -d tmpdir ]
$ echo $?
0
如您所见,-d
returns 目录存在时为 0(成功),否则为 1。同样,mkdir
returns 成功创建目录时为 0,否则为 1,但 mkdir -p
不认为文件已存在为错误。
问题在于 ||
是一个短路运算符。只有需要的才会被执行。因此,例如,在 true || echo Hello
中,echo Hello
永远不会被执行,因为 ||
的左侧始终为真。 &&
也是一个短路运算符,false && echo Hello
永远不会执行 echo Hello
,因为运算符的左侧始终为假。
牢记所有这些,很容易看出它是如何工作的:
- 如果目录存在,
-d
returns 0(成功)和其余操作数不需要计算(由于短路行为)
- 如果目录不存在,则执行
-d
return 1(失败)和mkdir -p
:
- 如果目录创建成功(记住如果目录已经存在
mkdir -p
不会return报错),mkdir -p
returns 0(成功)并且 echo msg
没有被执行(由于短路行为)
- 如果目录未成功创建,则评估
mkdir -p
returns 1(失败)和 echo msg
。它的退出状态是整个表达式的"value"。
我无法理解此 posix shell 代码的工作原理。
my_dir=/tmp/foo_dir
[ -d $my_dir ] || mkdir -p $my_dir || echo "Error creating '$my_dir'!"
考虑目录不存在的情况。
-d returns 如果目录不存在则为零,因此会评估 "mkdir"。
mkdir returns 成功后为零,这应该导致 "echo" 也被评估。但是此代码有效(echo
仅在通过将 my_dir
更改为 /ttmp/foo_dir"
导致目录创建失败时打印)
在posixshell中,0表示成功,其他值表示失败。当我们在逻辑表达式中使用命令时,我们正在测试它的退出状态。我们可以使用 $?
来检查最后的退出状态。
正在试验:
$ true
$ echo $?
0
$ false
$ echo $?
1
$ [ -d tmpdir ]
$ echo $?
1
$ mkdir tmpdir
$ echo $?
0
$ mkdir tmpdir
mkdir: tmpdir: File exists
$ echo $?
1
$ mkdir -p tmpdir
$ echo $?
0
$ [ -d tmpdir ]
$ echo $?
0
如您所见,-d
returns 目录存在时为 0(成功),否则为 1。同样,mkdir
returns 成功创建目录时为 0,否则为 1,但 mkdir -p
不认为文件已存在为错误。
问题在于 ||
是一个短路运算符。只有需要的才会被执行。因此,例如,在 true || echo Hello
中,echo Hello
永远不会被执行,因为 ||
的左侧始终为真。 &&
也是一个短路运算符,false && echo Hello
永远不会执行 echo Hello
,因为运算符的左侧始终为假。
牢记所有这些,很容易看出它是如何工作的:
- 如果目录存在,
-d
returns 0(成功)和其余操作数不需要计算(由于短路行为) - 如果目录不存在,则执行
-d
return 1(失败)和mkdir -p
:- 如果目录创建成功(记住如果目录已经存在
mkdir -p
不会return报错),mkdir -p
returns 0(成功)并且echo msg
没有被执行(由于短路行为) - 如果目录未成功创建,则评估
mkdir -p
returns 1(失败)和echo msg
。它的退出状态是整个表达式的"value"。
- 如果目录创建成功(记住如果目录已经存在