Shell 有效函数名字符

Shell 有效函数名字符

使用扩展 Unicode 字符(毫无疑问)对许多用户来说很有用。

更简单的 shell(ash (busybox)、dash)和 ksh 确实会失败:

tést() { echo 34; }

tést

,,, 和似乎允许它。

我知道 POSIX有效的函数名称使用这个定义名称。这意味着这个正则表达式:

[a-zA-Z_][a-zA-Z0-9_]*

然而,在第一个链接中也说:

实现可以允许函数名称中的其他字符作为扩展名。

问题是:

  • 这是否被接受并记录在案?
  • 在哪里?
  • 适用于哪些 shell(如果有)?

相关问题:
是否可以在 shell 函数名称中使用特殊字符?
我对在函数名称中使用元字符 (>) 不感兴趣。

Upstart 和 bash 函数名称中包含“-”
我不认为运算符(减法“-”)应该是名称的一部分。

答案1

由于 POSIX 文档允许将其作为扩展,因此没有什么可以阻止该行为的实现。

一个简单的检查(运行在zsh):

$ for shell in /bin/*sh 'busybox sh'; do
    printf '[%s]\n' $shell
    $=shell -c 'á() { :; }'
  done
[/bin/ash]
/bin/ash: 1: Syntax error: Bad function name
[/bin/bash]
[/bin/dash]
/bin/dash: 1: Syntax error: Bad function name
[/bin/ksh]
[/bin/lksh]
[/bin/mksh]
[/bin/pdksh]
[/bin/posh]
/bin/posh: á: invalid function name
[/bin/yash]
[/bin/zsh]
[busybox sh]
sh: syntax error: bad function name

表明bash, zsh, yash, ksh93ksh在我的系统中链接到)pdksh及其派生允许多字节字符作为函数名称。

yash 旨在支持多字节字符从一开始,所以它的成功也就不足为奇了。

您可以参考的其他文档是ksh93

空白是制表符或空格。标识符是以字母或下划线开头的字母、数字或下划线的序列。标识符用作变量名称的组成部分。 vname 是由 . 分隔的一个或多个标识符组成的序列。并可选地在前面加上 .. Vnames 用作函数和变量名称。一个单词是一个字符序列当前语言环境定义的字符集,不包括未引用的元字符。

因此设置为C区域设置:

$ export LC_ALL=C
$ á() { echo 1; }
ksh: á: invalid function name

使其失败。

答案2

请注意,函数与其他命令(包括文件系统中的命令)共享相同的命名空间,在大多数系统上,它们对其路径中可能包含的字符甚至字节没有限制。

因此,虽然大多数 shell 都限制其函数的字符,但它们并没有真正充分的理由这样做。这意味着在这些 shell 中,有些命令无法用函数替换。

zshrc允许其函数名称包含任何内容,包括一些 with/和空字符串。zsh甚至允许 NUL 字节。

$ zsh
$ $'\0'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test

shell 中的一个简单命令是一个参数列表,第一个参数用于派生要执行的命令。因此,这些参数和函数名称共享相同的可能值是合乎逻辑的,并且zsh内置函数和函数的参数可以是任何字节序列。

这里的功能不存在安全问题(脚本作者)定义的是那些调用。

当解析受到环境影响时,可能会出现安全问题,例如,在 shell 中,函数的有效名称会受到语言环境的影响。

相关内容