Shell 有效函数名字符

14 shell bash zsh function

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

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

tést() { echo 34; }

tést
Run Code Online (Sandbox Code Playgroud)

但是似乎允许它。

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

[a-zA-Z_][a-zA-Z0-9_]*
Run Code Online (Sandbox Code Playgroud)

但是,在第一个链接中还说:

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

问题是:

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

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

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

cuo*_*glm 16

由于 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
Run Code Online (Sandbox Code Playgroud)

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

yash 从一开始就旨在支持多字节字符,因此它的工作原理不足为奇。

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

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

所以设置为C语言环境:

$ export LC_ALL=C
$ á() { echo 1; }
ksh: á: invalid function name
Run Code Online (Sandbox Code Playgroud)

让它失败。


Sté*_*las 9

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

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

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

$ zsh
$ $'\0'() echo nul
$ ^@
nul
$ ""() uname
$ ''
Linux
$ /bin/ls() echo test
$ /bin/ls
test
Run Code Online (Sandbox Code Playgroud)

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

这里不存在安全问题,因为(脚本作者)定义的函数就是调用的函数。

可能存在安全问题的地方是解析受环境影响时,例如在 shell 中,函数的有效名称受语言环境影响。