POSIX shell 中函数和变量的单独命名空间

PSk*_*cik 14 shell dash posix

在 dash 中,函数和变量似乎位于不同的命名空间中:

fn(){
    fn="hello world"
}
fn; echo "The value is $fn!" #prints: The value is hello world!
fn; echo "The value is $fn!" #prints: The value is hello world!
#the fn variable doesn't conflict with the fn function
Run Code Online (Sandbox Code Playgroud)

这是特定于破折号的功能还是 POSIX 保证?

ilk*_*chu 14

保证

2.9.5 功能定义命令

函数是用户定义的名称,用作调用具有新位置参数的复合命令的简单命令。函数是用“函数定义命令”定义的。[...]

该函数名为 fname;应用程序应确保它是一个名称(请参阅 XBD 名称)并且它不是特殊内置实用程序的名称。实现可能允许函数名称中的其他字符作为扩展名。实现应为函数和变量维护单独的名称空间。


max*_*zig 8

变量和函数驻留在破折号中的不同命名空间中,这也由POSIX指定:

实现应为函数和变量维护单独的名称空间。

除此之外,默认情况下变量具有全局作用域。一些 shell(例如 bash、ksh 和 zsh)提供local关键字来在仅具有局部作用域的函数中声明变量。

所以,是的,你看到的行为是由 POSIX 保证的。

POSIX 尚未标准化 local

早期提案中对函数的描述基于函数应该像微型 shell 脚本一样运行的概念;也就是说,除了共享变量执行环境的大多数元素应该表现得好像它们是一个新的执行环境,[..]

[..] 函数内的局部变量被考虑并包含在另一个早期的提议中(由特殊的内置 控制local),但被删除,因为它们不适合为函数开发的简单模型,并且因为有一些反对添加另一个新的特殊内置,不是历史实践的一部分。实现应该保留标识符local(以及typeset在 KornShell 中使用的 ),以防在本标准的未来版本中采用这种局部变量机制。

(强调我的)