这两者有什么区别:
cnt=1
head -n $((++cnt)) /etc/passwd >/dev/null
echo $cnt # prints 2
和cnt=1
date >$((++cnt)).txt # creates file "2.txt"
echo $cnt # prints 1
我的问题是为什么在第二个示例中打印 1。笔记:
cnt=1
(cnt=5)
echo $cnt # prints 1
我知道为什么这会打印 1。重定向是否也在子 shell 中执行?如果是,在哪里描述的?
最佳答案
我没有具体的引文说明为什么会出现这种行为,但在 SC2257 中没有注释。 * 手册中有一些有趣的地方需要注意。
When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment
§3.7.3 Command Execution Environment
这反射(reflect)了 SC2257 指出的内容,尽管不清楚重定向的值是在哪个环境中计算的。但是 §3.1.1 Shell Operation似乎说重定向发生在调用此执行(子)环境之前:
Basically, the shell does the following:
...
- Performs the various shell expansions....
- Performs any necessary redirections and removes the redirection operators and their operands from the argument list.
- Executes the command.
我们可以看到,这不仅限于 arithmetic expansions还有其他改变状态的扩展,如
:=
:$ bash -c 'date >"${word:=wow}.txt"; echo "word=${word}"'
word=
$ bash -c 'echo >"${word:=wow}.txt"; echo "word=${word}"'
word=wow
有趣的是,这似乎不是(定义明确的)子 shell 环境,因为 BASH_SUBSHELL
仍然设置为 0
:$ date >"${word:=$BASH_SUBSHELL}.txt"; ls
0.txt
我们还可以检查一些其他的 shell,看到 zsh
具有相同的行为,但 dash
才不是:$ zsh -c 'date >"${word:=wow}.txt"; echo "word=${word}"'
word=
$ zsh -c 'echo >"${word:=wow}.txt"; echo "word=${word}"'
word=wow
$ dash -c 'date >"${word:=wow}.txt"; echo "word=${word}"'
word=wow
$ dash -c 'echo >"${word:=wow}.txt"; echo "word=${word}"'
word=wow
我浏览了 zsh
guide但也没有在那里找到对这种行为的确切提及。不用说 ,这似乎不是有据可查的行为,因此幸运的是,ShellCheck 可以帮助捕获它。然而,它似乎是长期存在的行为,它可以在 Bash 3、4 和 5 中重现。
* 不幸的是 commit that added SC2257不链接到问题或任何其他进一步的上下文。
关于linux - 重定向中的算术表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62783161/