使用扩展 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
, ksh93
(ksh
在我的系统中链接到)pdksh
及其派生允许多字节字符作为函数名称。
yash
旨在支持多字节字符从一开始,所以它的成功也就不足为奇了。
您可以参考的其他文档是ksh93
:
空白是制表符或空格。标识符是以字母或下划线开头的字母、数字或下划线的序列。标识符用作变量名称的组成部分。 vname 是由 . 分隔的一个或多个标识符组成的序列。并可选地在前面加上 .. Vnames 用作函数和变量名称。一个单词是一个字符序列当前语言环境定义的字符集,不包括未引用的元字符。
因此设置为C
区域设置:
$ export LC_ALL=C
$ á() { echo 1; }
ksh: á: invalid function name
使其失败。
答案2
请注意,函数与其他命令(包括文件系统中的命令)共享相同的命名空间,在大多数系统上,它们对其路径中可能包含的字符甚至字节没有限制。
因此,虽然大多数 shell 都限制其函数的字符,但它们并没有真正充分的理由这样做。这意味着在这些 shell 中,有些命令无法用函数替换。
zsh
并rc
允许其函数名称包含任何内容,包括一些 with/
和空字符串。zsh
甚至允许 NUL 字节。
$ zsh
$ $'\0'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test
shell 中的一个简单命令是一个参数列表,第一个参数用于派生要执行的命令。因此,这些参数和函数名称共享相同的可能值是合乎逻辑的,并且zsh
内置函数和函数的参数可以是任何字节序列。
这里的功能不存在安全问题你(脚本作者)定义的是那些你调用。
当解析受到环境影响时,可能会出现安全问题,例如,在 shell 中,函数的有效名称会受到语言环境的影响。