編寫可在任何 shell 上執行的 shell 腳本(使用多個 shebang 行?)

編寫可在任何 shell 上執行的 shell 腳本(使用多個 shebang 行?)

我剛開始深入了解 shell 腳本,我總是只是將腳本放入文件中,對其進行標記chmod +x,然後完成/path/to/script.sh,讓任何預設解釋器都可以使用它,我認為它是 zsh,因為這就是我用在我的外殼上。顯然,即使我從 zsh 提示符執行腳本,這似乎也是/bin/sh默認情況,因為我開始將 zsh 特定的內容放入腳本中,除非我運行zsh /path/to/script.sh.

為了切入主題,我的問題如下:

  1. #!/path/to/shell當開頭沒有 shebang 行 ( ) 時,哪個 shell 會執行腳本?我假設/bin/sh但我無法確認。
  2. 在編寫可在任何平台上運行的 shell 腳本方面,什麼被認為是「最佳實踐」? (好吧,這是一種開放式的)
  3. 是否可以編寫一個嘗試使用 zsh 的腳本,如果 zsh 不可用則回退到 bash?我嘗試過放置兩條 shebang 行,如下所示,但bad interpreter: /bin/zsh: no such file or directory如果我在沒有 zsh 的機器上嘗試它,它就會出錯。

    #!/bin/zsh

    #!/bin/bash

答案1

當開頭沒有 shebang 行 (#!/path/to/shell) 時,哪個 shell 會執行腳本?我假設 /bin/sh 但我無法確認。

核心拒絕執行此類腳本並傳回 ENOEXEC,因此確切的行為取決於執行此類腳本的程序

  • bash 4.2.39 – 使用自身
  • busybox-ash 1.20.2 – 使用自身
  • dash 0.5.7 – 運行 /bin/sh
  • Fish 1.23.1 – 抱怨 ENOEXEC,然後歸咎於錯誤的文件
  • AT&T ksh 93u+2012.08.01 – 使用自身
  • mksh R40f – 執行 /bin/sh
  • pdksh 5.2.14 – 運行 /bin/sh
  • sh-heirloom 050706 – 使用自身
  • tcsh 6.18.01 – 運行 /bin/sh
  • zsh 5.0.0 – 執行 /bin/sh
  • cmd.exe 5.1.2600 – 看著你很有趣。

glibc、函數execv()execve()僅傳回 ENOEXEC。但execvp()隱藏此錯誤代碼並自動呼叫/bin/sh。 (這記錄在執行(3p).)

在編寫可在任何平台上運行的 shell 腳本方面,什麼被認為是「最佳實踐」? (好吧,這是一種開放式的)

要嘛堅持sh並且只使用 POSIX 定義的功能,要嘛就完全使用巴什(廣泛可用)並在分發時在您的要求中提及它。

(現在我想起來了,Perl——或者也許是 Python——會更加可移植,更不用說有更好的語法了。)

總是新增 shebang 行。如果使用 bash 或 zsh,請使用#!/usr/bin/env bash而不是硬編碼 shell 的路徑。 (但是,POSIX shell 保證位於/bin/sh,因此env在這種情況下請跳過。)

(不幸的是,even/bin/sh並不總是相同的。GNU自動配置程式必須處理許多不同的怪癖.)

是否可以編寫一個嘗試使用 zsh 的腳本,如果 zsh 不可用則回退到 bash?我嘗試放置兩條 shebang 線,如下所示,但它只是錯誤錯誤的解釋器:/bin/zsh:沒有這樣的檔案或目錄如果我在沒有 zsh 的機器上嘗試一下。

shebang 行只能有一條;換行符號之後的所有內容甚至不會被核心讀取,並被 shell 視為註解。

它是可能的編寫一個執行為 的腳本#!/bin/sh,檢查哪個 shell 可用,然後根據結果執行exec zsh "$0" "$@"或。exec bash "$0" "$@"然而,bash 和 zsh 使用的語法在不同地方有很大不同,我會不建議這樣做為了你自己的理智。

答案2

1) 目前運行的 shell。

2) 堅持使用相同的 shell 類型(bash/dash/ash/csh/無論您喜歡什麼),並確保您的「支援的平台」預設安裝您希望使用的 shell。另外,嘗試使用系統上常用的命令。避免特定於機器的選項。

3)其實並沒有「if-then-else」邏輯interpreter directive。您應該指定一個應該存在於您希望支援的所有系統上的 shell...即,#!/bin/bash或指定一個通用的#!/bin/sh,只要您的腳本在所有 shell 中相當通用。

相關內容