linux - 重定向中的算术表达式

标签 linux bash

这两者有什么区别:

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:
...

  1. Performs the various shell expansions....
  2. Performs any necessary redirections and removes the redirection operators and their operands from the argument list.
  3. 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/

相关文章:

json - jq 以科学记数法重新格式化小数——这可以避免吗?

linux - bash:如何在 for 循环中访问 "dynamic declared variable"

linux - 这个组合命令 :() { :|:& }; : work? (CAUTION : don't try, 导致系统停止)

linux - Linux 上的多行 Tabbar 文本编辑器

linux - 如何从命令输出生成交互式 'dialog' list ?

linux - 检查防火墙是否打开,没有像 iptables 这样的包

linux - 在适用于 Linux 的 Windows 子系统上的 Ubuntu 上使用 INT 0x80 汇编编译的可执行文件不产生输出

linux - 为什么我在 shell 中键入 linux 中的时间命令与在脚本中使用它时输出不同?

linux - 检查目录是否已更改

linux - 从用户空间启用/读取 PMU