函數、別名和可執行檔中的連字號是否有問題?

函數、別名和可執行檔中的連字號是否有問題?

在我的測試中(在 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。

相關內容