首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >$-在执行重定向时未按预期执行扩展。

$-在执行重定向时未按预期执行扩展。
EN

Unix & Linux用户
提问于 2019-05-17 01:14:21
回答 1查看 105关注 0票数 4

在以下情况下,bashzsh将在子进程中执行变量和算术扩展

( a)他们跟踪的是一个重定向操作符,如<>>><<<

( b)他们参与的命令不是内置的或函数。

代码语言:javascript
复制
bash -c 'i=0; /bin/echo > $((i=7)).txt; echo $i'
0
zsh -c 'i=0; /bin/echo > $((i=7)).txt; echo $i'
0

ksh -c 'i=0; /bin/echo > $((i=7)).txt; echo $i'
7

上面的ksh和除bashzsh之外的任何其他shell一样。

这与那些算术展开无关:类似地,同样的事情也发生在

代码语言:javascript
复制
unset i; /bin/echo >${i:=7}.txt; echo $i

将只在bashzsh以外的shell中打印D13

然而,就好像这还不够糟糕一样,bashzsh之间的行为在任何深奥的方面都不一致:

代码语言:javascript
复制
bash -c 'i=0; command echo > $((i++)).txt; echo $i'
1
zsh -c 'i=0; command echo > $((i++)).txt; echo $i'
0

bash -c 'i=0; i=$i /usr/bin/printenv i > $((++i)).bash; echo $i; cat *.bash'
0
0
zsh -c 'i=0; i=$i /usr/bin/printenv i > $((++i)).zsh; echo $i; cat *.zsh'
0
1

所以,我的问题是:What标准中说吗?这可以接受吗?

我能够找到很多关于变量赋值的信息,比如在KEY=val cmd中,以及它们是否“影响到当前的执行环境”,但是对于重定向、$-expansions和外部命令之间的交互却没有发现。

它不可能也适用于作为$-expansions的一部分完成的变量赋值,因为ls $((i=2+3))会导致在所有shell中将i设置为5,而不管ls是外部命令还是内置的。

EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2019-05-17 18:41:01

这是未指定的,因此每个shell都可以做它想做的事情,而不必记录细节。(从历史的角度来看,之所以没有具体说明,是因为不同的shell所做的事情不同。)从技术上讲,贝壳可以抛硬币。在实践中,在单独的环境中运行的内容和不运行的细节可能取决于在某些情况下所做的优化,例如,取决于命令是否是内置的,取决于重定向是否指向/从/dev/null,取决于陷阱是否活动,取决于set -e是否有效,取决于命令是否是列表中的最后一个命令,等等。

来自SUSv4 (POSIX.1-2008年) “壳牌和实用程序”-§2.9.1“简单命令”

如果命令名不是一个特殊的内置实用程序或函数,则变量赋值应导出到命令的执行环境,并且除作为步骤4中执行的扩展的副作用外,不影响当前的执行环境。在这种情况下,未指定:

  • 对于步骤4中的后续扩展而言,这些任务是否可见?
  • 作为这些扩展的副作用进行的变量赋值对于步骤4或当前shell执行环境中的后续扩展是否可见,或者两者都可见。

为了澄清:“步骤4”包括参数展开(例如${i:=7})和算术展开(例如$((i=7)))。“不影响当前执行环境”的变量扩展是命令前面的变量,例如i=7 ls。因此,这一段除其他外说,如果参数展开或变量展开修改了变量的值,那么在命令返回后,这是否会产生影响,这是一个未知数。

在实践中,shell通常通过先分叉,然后在子shell中重定向,将重定向应用于外部命令。但是,在创建子subshell之前还是之后,它们在确定重定向的目标时有所不同。

票数 3
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/519398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档