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

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

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

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

我犹豫是否相信这不是问题的一个原因是,在某些语言(例如 Ruby)中,即使连字符周围没有空格,连字符也会被解释为减号。如果在某些 shell 中发生类似的情况,我不会感到惊讶,其中连字符被解释为即使没有空格也表示一个选项。

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

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

答案1

POSIX 和连字符:没有保证

根据 POSIX 标准,函数名必须是有效的名称并且一个名字可以包括:

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

此外,别名必须是有效的别名,它可以包括:

3.10 别名
在 shell 命令语言中,仅由可移植字符集中的下划线、数字和字母以及以下任意字符组成的单词:“!”、“%”、“,”、“@”。

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

连字符是不是列出在任何一种情况下都必须允许的字符。因此,如果使用它们,则无法保证可移植性。

不支持连字符的 shell 示例

dash是 debian-ubuntu 系列上的默认 shell ( /bin/sh),它不支持函数名称中的连字符:

$ 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 shell(仅基于 ash 的 shell)也不支持函数名称中的连字符:

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

Shell 支持的连字符摘要

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

  • pdksh 及其衍生品、bash、zsh
  • 一些 ash 衍生品,例如 FreeBSD 的 sh (自2010年以来)或 NetBSD(自 2016 年起)。
  • busybox sh 当编译时选择的 shellhush不是ash.
  • csh 和 tcsh(在它们的别名中,这些 shell 没有功能支持)。无论如何,这些 shell 具有完全不同的语法,因此不可能与这些 shell 具有跨 shell 兼容性。
  • rc 和导数(同样使用完全不同的语法)
  • 鱼(同样具有完全不同的语法)

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

  • Bourne shell 及其衍生产品,例如 ksh88 和 bosh(在 Bourne shell 中,函数和变量共享相同的命名空间,不能有同名的变量和函数)。
  • ksh93、yash、原始 ash 及其一些衍生品(busybox ash(sh 的默认选择)、dash)

结论

  • 连字符是非标准的。如果您想要跨外壳兼容性,请远离它们。
  • 使用下划线而不是连字符:下划线在任何地方都被接受。

答案2

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

xmodmap -e "keycode  20 =  underscore minus"

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

所以现在,您按住 Shift 键作为连字符,但键入下划线时无需使用 Shift 键。

您的键码可能会有所不同,但是,我认为这取决于您的键盘;我的正好是 20。如果您需要帮助查找您需要使用的密钥代码,请告诉我。

相关内容