在多個 shell 上執行腳本?
我有兩台伺服器,一台具有預設 shell ksh 的 AIX,另一台具有預設 shell bash 的 RHEL。
我有一個安裝在兩者上的腳本,它將執行類似的命令,但適用於 AIX 或 Linux。這個腳本在 bash 伺服器上不起作用,有沒有辦法讓這個腳本在 bash 和 ksh 上執行,或者最好的選擇是創建兩個不同的腳本?
#!/usr/bin/ksh export OS=`uname -s` echo "OS is "$OS"." case $OS in "AIX") #run AIX commands;; "Linux") #run Linux commands;; "*") echo "Exiting. The OS type is not found.";; esac echo "Done." exit 0
更新
我需要執行的命令適用於每台伺服器上的使用者帳戶。解鎖帳戶的範例。AIX /usr/bin/chuser account_locked=false $USERNAME
Linux /usr/bin/passwd -u $使用者名
通過進一步調查,我發現 AIX 中的 shell 位於 /usr/bin/sh,而 Redhat 位於 /bin/sh。
我可以根據“uname”的結果定義shebang嗎?
擁有兩個單獨的腳本版本可能會更容易。由於它很短,因此可能不值得添加額外的程式碼來處理 jw013 建議的兩種格式之間的差異。另一方面,如果您有一個更大的腳本,那麼擁有一個腳本並根據其執行位置使腳本執行不同的命令可能會更容易。
到目前為止,最簡單的方法是在兩個系統上使用相同的 shell。僅僅因為預先安裝了一個 shell(沒有腳本的“預設 shell”之類的東西,shell 就是 shebang 行所說的)並不意味著您不能安裝其他 shell。您可以在 AIX 上安裝 bash(例如,從toolbox)或在 Linux 上安裝 ksh93(使用您的發行版的包管理器:安裝
ksh
包)。如果您選擇 ksh,請注意
/usr/bin/ksh
AIX 上是 ksh88。沒有適用於 Linux 的 ksh88 版本,只有 ksh93,它/usr/bin/ksh93
在 AIX 上可用。如果相同的 shell 安裝在兩個系統的相同位置會更容易(符號連結很好),這樣您就可以在 shebang 行中使用相同的路徑。如果有相同的位置太難了,你可以使用類似的東西
#!/usr/bin/env bash
,只要你確保它bash
在PATH
兩個系統上。如果您必須在主目錄中安裝 bash 或 ksh,這可能會很有用,因為您沒有 root 訪問權限。如果你真的不能在兩台機器上安裝相同的外殼——大概是因為有一些愚蠢的合規性規則只會使人們的生活複雜化,但又根深蒂固而無法推翻——你有幾種可能性。
- 在
#!/bin/sh
您的系統提供的產品中用作您的 shebang 線路和程序。所有現代 unix 系統都提供POSIX shell作為/bin/sh
. 在 AIX 上,/bin/sh
是 ksh88。在 Red Hat 上,/bin/sh
是 bash(當呼叫為 時,其行為略有不同sh
)。請注意,在某些其他作業系統上(例如,在許多 Linux 發行版上),/bin/sh
是一個較小的 shell,它可能沒有比 POSIX 更多的功能。- 使用一些樣板程式碼開始您的腳本,這些程式碼會尋找更好的 shell 並執行它。
#!/bin/sh if [ -n "$BASH" ]; then … bash compatibility code … elif type whence >/dev/null 2>/dev/null; then … ksh compatibility code … elif type ksh93 >/dev/null 2>/dev/null; then exec ksh93 "$0" "$@" elif type ksh >/dev/null 2>/dev/null; then exec ksh "$0" "$@" elif type mksh >/dev/null 2>/dev/null; then exec mksh "$0" "$@" elif type bash >/dev/null 2>/dev/null; then exec bash "$0" "$@" else echo 1>&2 "Cannot find ksh or bash, aborting" exit 125 fi
無論哪種情況,ksh88 和 bash 的交集都提供了一些 POSIX 之外的有用功能,但您可能需要一些兼容性程式碼。尤其:
- ksh88 中的數組賦值使用
set -A
. 查看不同ksh環境下的賦值變數- 局部變數由
typeset
.- Ksh88 沒有
${VAR/PATTERN/REPLACEMENT}
,$'…'
或FIGNORE
. 它確實有[[ … ]]
。- 要在 bash 中啟用
@(…)
和其他 ksh 擴展模式,請執行shopt -s extglob
.