Linux

#!/bin/sh vs #!/bin/bash 以獲得最大的可移植性

  • August 1, 2017

我通常使用 Ubuntu LTS 伺服器,從我理解的符號連結/bin/sh/bin/dash. 許多其他發行版雖然符號連結/bin/sh/bin/bash.

據我了解,如果腳本#!/bin/sh在頂部使用它可能不會在所有伺服器上以相同的方式執行?

當人們希望這些腳本在伺服器之間具有最大的可移植性時,是否有關於使用哪個 shell 來執行腳本的建議做法?

shell 腳本的可移植性大致有四個級別(就 shebang 行而言):

  1. 最便攜:使用#!/bin/shshebang 並僅使用POSIX 標準中指定的基本 shell 語法。這應該適用於幾乎任何 POSIX/unix/linux 系統。(好吧,除了 Solaris 10 和更早版本,它具有真正的遺留 Bourne shell,早於 POSIX,因此不兼容,如/bin/sh.)
  2. 第二最便攜:使用#!/bin/bash(或#!/usr/bin/env bash)shebang 行,並堅持使用 bash v3 功能。這適用於任何具有 bash 的系統(在預期位置)。
  3. 第三最便攜:使用#!/bin/bash(或#!/usr/bin/env bash)shebang 行,並使用 bash v4 功能。這將在任何具有 bash v3 的系統上失敗(例如 macOS,出於許可原因必須使用它)。
  4. 最不便攜:使用#!/bin/shshebang 並使用 POSIX shell 語法的 bash 擴展。這將在任何具有 bash 以外的 /bin/sh 的系統(例如最近的 Ubuntu 版本)上失敗。永遠不要這樣做;這不僅僅是一個兼容性問題,它完全是錯誤的。不幸的是,這是很多人犯的錯誤。

我的建議:使用前三個中最保守的一個,它提供腳本所需的所有 shell 功能。為了獲得最大的可移植性,請使用選項#1,但根據我的經驗,一些 bash 功能(如數組)非常有用,我將使用 #2。

您可以做的最糟糕的事情是#4,使用錯誤的shebang。如果您不確定哪些功能是基本 POSIX 以及哪些是 bash 擴展,請堅持使用 bash shebang(即選項 #2),或者使用非常基本的 shell(例如 Ubuntu LTS 伺服器上的 dash)徹底測試腳本。Ubuntu wiki 有一個很好的 bashisms 列表來提防

在 Unix 和 Linux 問題“sh 兼容意味著什麼?”中有一些關於 shell 的歷史和差異的非常好的資訊。和 Stackoverflow 問題“sh 和 bash 之間的區別”

另外,請注意,shell 並不是不同系統之間唯一不同的東西。如果你習慣了 linux,那麼你就習慣了 GNU 命令,這些命令有很多在其他 unix 系統(例如 bsd、macOS)上可能找不到的非標準擴展。不幸的是,這裡沒有簡單的規則,你只需要知道你正在使用的命令的變化範圍。

就可移植性而言,最討厭的命令之一是最基本的命令之一:echo. 任何時候您將它與任何選項(例如echo -nor echo -e)或字元串中的任何轉義符(反斜杠)一起使用時,不同的版本會做不同的事情。任何時候你想列印一個沒有換行符的字元串,或者在字元串中使用轉義符,請printf改用(並了解它是如何工作的——它比echo現在更複雜)。ps命令也是一團糟

另一個需要注意的一般事情是命令選項語法的最新/GNUish 擴展:舊的(標準)命令格式是命令後跟選項(帶有單個破折號,每個選項是單個字母),然後是命令參數。最近(通常是不可移植的)變體包括長選項(通常與 一起引入--),允許選項出現在參數之後,並--用於將選項與參數分開。

引用自:https://serverfault.com/questions/865874