Nic*_*ull 1 shell subshell math
当我在 中执行一个简单的数学运算时#!/bin/sh,是否会创建一个子shell?
例如,
addition=$(( 1 + 1 ))
Run Code Online (Sandbox Code Playgroud)
语法会建议一个子shell,但我在这上面找不到任何东西
$(cmd arg)cmd在子shell环境中运行,其输出(减去尾随换行符)成为扩展的结果。
(cmd arg) 确实在子shell中运行,其输出不受影响。
所以$((cmd arg))将与$(cmd arg)但具有额外的子壳层相同,除了它不是。
$((...))是来自 Korn shell 的一种单独的扩展形式。在 Korn shell 中,((arithmetic expression))计算算术表达式(遵循与 C 非常相似的语法)并且退出状态反映表达式是解析为 0 还是非零。
这允许以下内容:
if ((var < 10)); then
...
fi
Run Code Online (Sandbox Code Playgroud)
这使它看起来非常类似于C.
$用于引入扩展。就像$(cmd)是一样(cmd),除了它膨胀到的输出cmd,$((arith))就像是((arith))除了它膨胀到算术表达式的求值的结果。
POSIX,其sh主要基于 ksh88,指定$((...))但不是((...)). 实际上,在较早的草稿中,它是要$[...]替代的,这就是为什么您发现它bash并zsh支持$[...]作为$((...)).
IIRC,POSIX 最初想到将其指定为的主要原因$[...]是因为$((...))与$((cmd arg))命令替换中的子shell冲突。
您会发现大多数 shell 正确识别$((echo x; echo y) | (tr xy ab))为不是算术扩展,而不是$((cmd arg)). 在任何情况下$((cmd))都意味着扩展到$cmd变量的算术值,而不是扩展到 的输出cmd。
POSIX 规范中的相关文本有:
shell 命令语言的语法对于以“$((”)开头的扩展有歧义,它可以引入算术扩展或以子shell 开头的命令替换。算术扩展具有优先权;也就是说,shell 应首先确定是否它可以将扩展解析为算术扩展,并且只有在确定不能将扩展解析为算术扩展时才将扩展解析为命令替换。外壳在执行此确定时不需要评估嵌套扩展。如果遇到结束如果输入没有确定不能将扩展解析为算术扩展,shell 会将扩展视为不完整的算术扩展并报告语法错误。符合要求的应用程序应确保在以子shell 开头的命令替换中将“$(”和“(”) 分隔为两个标记(即,将它们用空格分隔)。例如,包含单个子shell 的命令替换可以写成:
ksh的((...))还嵌套子shell冲突。虽然 POSIX 没有指定((...)),但它确实允许 ksh 的行为。
在实践中,当嵌套 subshell 和/或 cmdsubsts 时,您应该确保在括号之间包含空格:
echo "$( (...) )"
( (a; b) | (c;d) )
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
282 次 |
| 最近记录: |