函数是否在Bash中作为子流程运行?


28

Advanced Bash-Scripting Guide中,在示例27-4(从底部开始的第7行)中,我已阅读以下内容:

函数作为子流程运行。

我在Bash中进行了测试,似乎以上陈述是错误的。

在本网站Bash Man和我的搜索引擎上进行的搜索没有任何帮助。

您有答案并想解释吗?


12
如前所述,该指南具有极端的误导性。我推荐使用《Wooledge Bash指南》
通配符

Answers:


36

《高级Bash脚本指南》并不总是可靠的,并且其示例脚本包含过时的做法,例如使用有效弃用的反引号代替命令,`command`而不是$(command)

在这种情况下,这显然是不正确的。

(规范的)Bash手册中有关Shell函数的部分明确指出:

Shell函数是在当前Shell上下文中执行的;没有创建新的过程来解释它们。


10
“高级Bash脚本指南通常是不可靠的” 非常正确。
John1024 '16

1
您能提供参考来支持您的第一句话吗?
Will Vousden

5
@WillVousden这里的参考会是什么样子?指南的技术不足的一堆例子?bash社区的专家先前曾指出该文件不可靠吗?如果bash中带有金牌的stackoverflow成员刚刚在评论中表示同意,这会有所帮助吗?:p
kojiro

3
@WillVousden我不认为您想要的东西本身以可靠的形式存在。Mendel Cooper过去已更新并修复了该指南的问题,但没有公共错误跟踪器或勘误表。(也许这是我能做的最该死的声明。)因此,当我们发现缺陷(感知的或真实的)时,我们所能做的就是向作者发送电子邮件,并希望做到最好。
kojiro

3
@WillVousden,...如果您想了解freenode #bash通道中应避免使用ABS的共识的历史,请参阅wooledge.org/~greybot/meta/abs-每行的第二个字段是时间戳,第一个是用户名;我希望断言所讨论的用户名非常受人尊敬的个人就足够了。
查尔斯·达菲

32

括号函数将在调用shell进程中运行,除非它们需要自己的子shell,即:

  • 当您在后台运行它们时 &
  • 当您将它们作为管道中的链接运行时

重定向或额外的环境。变量不会强制使用新的子shell:

hw(){
    echo hello world from $BASHPID
    echo var=$var
} 
var=42 hw >&2
echo $BASHPID  #unexports var=42 and restores stdout here

如果您使用括号而不是curl定义函数:

hw()(
  echo hello world from $BASHPID
)
hw 
echo $BASHPID

它将始终在新过程中运行。

命令替换$()也总是在bash中创建进程(但如果在内部运行内置命令,则不会在ksh中创建进程)。


我不知道f() (...)是允许的。除{...}和之外,还有其他定义(...)吗?在Bash中,我还不喜欢其他人。
Tomasz

1
@tomas可以使用function hw { echo hello world; } 语法(()如果键入,则不需要function,您可以在final之后})如中指定重定向hw(){ echo error; } >&2。就是这样
。– PSkocik

2
这是我立即想到的答案,这是绝对正确的。应该将其投票为正确答案。f()(...)总是执行自己的shell,而f(){...}不会执行。
rexkogitans

11
NB bash函数接受任何复合命令,foo() [[ x = x ]]有效的函数定义也是如此。但是,如果您与一起看功能,type foo您会发现这仍然是的语法糖foo() { [[ x = x ]]; }。子外壳函数也是如此:bar() ( : )变为bar() { ( : ); }
kojiro

1
@kojiro不错+1。不知道
PSkocik

9

该示例中涉及的命令如下所示:

echo ${arrayZ[@]/%e/$(replacement)}

后面的示例指出:

#    $( ... ) is command substitution.
#    A function runs as a sub-process.

出于对ABS指南的慈善,他们显然打算写的是,该函数在命令替换内运行,而命令替换内的命令在subshel​​l中运行。


这是非常误导的。感谢您的解释。
Tomasz

5
@tomas “非常令人误解。” 是的,非常。与ABS指南相反,Greg的Wiki是高级bash信息的绝佳来源。
John1024 '16

1
干杯。您对此有何看法:wiki.bash-hackers.org/start
Tomasz

@tomas我没有第一手的知识。
John1024 '16

2
@tomas,...我对bash-hackers Wiki的个人看法是,它是一个很好的来源。我没有像Wooledge Wiki那样全面地研究过它,但是它往往是准确而精确的。
查尔斯·达菲
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.