Sh泄漏函数调用中定义的变量(但不是命令调用)

时间:2018-03-19 09:52:16

标签: bash sh

即使我的系统上的同一个软件包提供了bash和sh,也存在差异:

在bash中:

$ echo $auie

$ auie=1 ls

$ echo $auie

$ testfn() { : ; }
$ auie=1 testfn
$ echo $auie
# Nothing

auie仅针对调用(ls,testfn)定义,并且不会泄漏到环境中。

在sh:

$ echo $auie

$ auie=1 ls

$ echo $auie

$ testfn() { : ; }
$ auie=1 testfn
$ echo $auie
1

这里,auie仅为ls调用定义,但是当函数调用发生时,它会“泄漏”到环境中!

为什么sh表现如此?

1 个答案:

答案 0 :(得分:1)

查看此page of the POSIX spec,似乎未定义auie的值在调用testfn后是否应该保持不变:

  
      
  • 如果命令名称是不是作为函数实现的标准实用程序的函数,则变量赋值将在函数执行期间影响当前执行环境。它没有说明:

         
        
    • 在功能完成后,变量赋值是否仍然存在
    •   
  •   

根本不清楚为什么bash会根据调用方式选择两种不同的行为。我的猜测是bash-as-sh保留了与其他shell(ksh [保留了值]或原始Bourne shell)的向后兼容性,而bash - 正确实现了作者所考虑的内容“更好的“行为。

在非详尽测试中,我可以确认dashksh会保留该值,而bashzsh则不会。

% for sh in bash dash ksh zsh; do
for> echo $sh; $sh -c 'testfn () { : ; }; auie=1 testfn; echo $auie;'
for> done
bash

dash
1
ksh
1
zsh

192%