Shell有效的函数名称字符


13

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

更简单的shell(灰(busybox),破折号)和ksh会因以下原因而失败:

tést() { echo 34; }

tést

但是似乎允许这样做。

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

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

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

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

问题是:

  • 是否接受并记录了此文件?
  • 哪里?
  • 对于哪些壳(如果有)?

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

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


您可能会发现alias宽大一点。因此,您可以使用一个适当的,按按钮按下的名称来编写函数,然后只需定义一个更时尚的命名别名即可调用该函数。在dash其中,您还可以使用$PATH和进行一些操作%func
mikeserv

Answers:


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

表明bashzshyashksh93(它ksh挂在我的系统),pdksh以及它的衍生允许多字节字符函数名。

yash 从一开始就设计为支持多字节字符,因此毫不奇怪。

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

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

因此设置为C语言环境:

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

使它失败。


posh不值得在这样的列表中列出。它取决于Linux中特定的错误,libc在其他平台上将不起作用。
schily '18

我无法重复您关于ksh93使用原始来源的自编译ksh93的声明。虽然ksh88函数名称似乎接受非7位ASCII字母,但只有ksh93Ubuntu 的二进制文件似乎接受它们。
schily '18

我在此测试中使用的@schily ksh是Debian中的二进制文件(因此可能与Ubuntu上的二进制文件相同)
cuonglm

9

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

因此,尽管大多数shell限制了其功能的特征,但并没有充分的理由解释为什么这样做。这意味着在这些shell中,有些命令不能用函数替换。

zshrc为其函数名称提供任何名称,包括带有/和的空字符串。zsh甚至允许NUL字节。

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

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

这里没有安全性问题,因为(脚本作者)定义的功能就是调用的功能。

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


一个可能在bash的游戏也开始function /bin/sh { echo "$0: $FUNCNAME: Permission denied"; return 126; }使用命名的功能,潜在有用的东西太多--//@%
mr.spuratic

但是,当/在名称中找到壳时,难道shell不会绕过哈希表查找吗?一个函数不仅仅是一个可执行文件名-它的代码。我认为,如果一个简单的实现的存储函数名称包含元字符,则可能会遇到很多解析问题。
mikeserv

是的,我知道bash无法在vars中包含null,可以合理地扩展为函数名称。我没有一个具体的例子,但我确实认为允许几乎所有名称使用名称的游戏更多地是潜在的安全漏洞,而不是“简单的工作方式”。我希望我错了。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.