如何測試 shell 腳本的 POSIX 合規性?
考慮到 POSIX 是所有 unice 中最接近通用標準的東西,我很想知道是否有一個 shell 專門支持它。雖然大多數現代 shell 提供對 POSIX 的支持(並且將毫無問題地執行符合 POSIX 的腳本),但它們在指出不符合要求的特性方面做得併不好。
是否有任何僅實現 POSIX 和 POSIX 的外殼程序,這樣它會為任何不兼容的功能拋出錯誤?
編輯我想澄清一下,我不是在要求編寫可移植 shell 腳本的一般技巧。評論中提到的相關問題已經涵蓋了這一點。當我發現
bash
有一個--posix
選項時,我想到了這個問題,但只是發現它只會影響一些不完全是我想要的初始化行為。
不幸的是,對於 shell 腳本,“便攜”通常比“符合 POSIX”的要求更強。也就是說,編寫在任何 POSIX shell 上執行的東西並不太難,但讓它在任何現實世界的 shell 上執行就更難了。
您可以從在包管理器中安裝每個 shell 開始,特別是 debian 的
posh
聲音如您所願(符合策略的普通 SHell)。Debian 的策略是 POSIX,但有一些例外(已echo -n
指定,local
…)。但除此之外,測試還必須涵蓋一系列平台上的一些 shell(尤其是 /bin/sh)。我在 Solaris(/bin/sh 和 xpg4/sh)和 BSD 上進行測試。AIX 和 HP-UX 非常合規,不會引起問題。bash 是一個自己的小世界。
我推薦Autoconf 指南到攜帶式 shell,它絕對很棒並且可以節省大量時間。其中大部分已經過時,但沒關係;如果您不在乎,請跳過 TruUnix 和 Ultrix 等!
你可以使用ShellCheck (GitHub)作為你的 shell 腳本的 linter。還有一個線上版本。
要檢測 POSIX 兼容性問題(例如SC2039),您的 shell 腳本的shebang 行應該是
#!/bin/sh
. 您也可以傳遞--shell=sh
給shellcheck
.範例 (
test.sh
):#!/bin/sh if [[ $HOSTNAME == test ]]; then echo fail &> foo fi
結果(
shellcheck test.sh
):In test.sh line 2: if [[ $HOSTNAME == test ]]; then ^-- SC2039: In POSIX sh, [[ ]] is undefined. ^-- SC2039: In POSIX sh, HOSTNAME is undefined. In test.sh line 3: echo fail &> foo ^-- SC2039: In POSIX sh, &> is undefined.