函数,别名和可执行文件中的连字符是否存在问题?


25

在我的测试中(在Bash和Z Shell中),我发现定义函数或别名或名称中带有连字符的可执行Shell脚本没有问题,但是我不确定在所有Shell和所有用例中都可以做到这一点。

我想这样做的原因是连字符比下划线更容易键入,因此更快捷,更流畅。

我不敢相信这不是问题的一个原因是,在某些语言(例如Ruby)中,即使连字符之间没有空格,连字符也会被解释为减号。如果在某些shell中可能会发生类似的事情,这也不会令我感到惊讶,在连字符中连字符被解释为即使没有空格也会发出信号。

我有点怀疑的另一个原因是我的文本编辑器搞砸了带有连字符的函数的语法高亮显示。(但是,当然,这很可能只是shell脚本的语法高亮显示配置中的一个错误。)

有什么理由避免连字符吗?

Answers:


32

POSIX和连字符:不保证

根据POSIX标准,函数名称必须是有效名称,并且名称可以包含:

3.231名称
在shell命令语言中,仅由下划线,数字和便携式字符集中的字母组成的单词。名称的第一个字符不是数字。

另外,别名必须是有效的别名,该别名可以包括:

3.10别名
在外壳命令语言中,仅由下划线,数字和可移植字符集中的字母和以下任何字符组成的单词:'!','%',',','@'。

实现可能允许别名中的其他字符作为扩展名。 (强调我的。)

在这两种情况下必须允许的字符中没有列出连字符。因此,如果使用它们,则不能保证可移植性。

不支持连字符的Shell的示例

dash/bin/shdebian-ubuntu家族的默认shell(),它不支持函数名中的连字符:

$ a-b() { date; }
dash: 1: Syntax error: Bad function name

有趣的是,它确实支持别名中的连字符,但是,如上所述,这是实现特性,而不是要求:

$ a_b() { printf "hello %s\n" "$1"; }
$ alias a-b='a_b'
$ a-b world
hello world

busybox外壳程序(Almquist外壳程序)也不支持函数名称中的连字符:

$ a-b() { date; }
-sh: Syntax error: Bad function name

壳牌对连字符的支持摘要

已知以下外壳程序在函数名称中支持连字符:

  • ksh,bash,zsh

已知以下shell 支持函数名称中的连字符:

  • 灰(busybox),csh,tcsh,破折号

结论

  • 连字符是非标准的。如果要跨外壳兼容,请远离它们。
  • 使用下划线代替连字符:下划线在任何地方都可以接受。

2
其中带有名字-是邪恶的。我在看着你,CSS。:)
PM 2Ring

谢谢。我在以后的测试csh,并tcsh和他们没有任何支持连字符,但Korn shell的那样。我也使用a-b()了我的函数名,这有点可笑。
iconoclast 2014年

@iconoclast我将您的shell测试结果添加到了答案中。谢谢。
John1024

@ PM2Ring比带有下划线的名称更容易键入。排除不允许它们的系统的传统或实施决策,您可以指出什么原则来支持它们是邪恶的主张?
iconoclast

1
@iconoclast在许多语言中都不能使用带连字符的名称,因为连字符被解释为减号,因此,如果这种语言需要与支持带连字符的名称的语言进行互操作,则会出现混乱的情况,即带有连字符名称的实体被迫在另一种语言中具有不同的名称。
下午18年

3

我知道这真的来晚了,但是也许您可以解决使下划线更易于访问的问题。

xmodmap -e "keycode  20 =  underscore minus"

这将用连字符(负)切换下划线。

因此,现在您为连字符设置了移位,但是键入的下划线没有移位。

您的键码可能有所不同,但是,我认为它取决于您的键盘。我的碰巧是20岁。请告诉我是否需要帮助,以找到需要使用的键码。

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.