Bash Shebang 適合傻瓜嗎?

Bash Shebang 適合傻瓜嗎?

我設定了一些主要使用的 bash 腳本

#!/bin/bash

但我常常遇到一些看起來像

#!/bin/bash -e
#!/bin/bash -x
#!/bin/bash -ex

等等。

有人可以解釋這些 shebang 選項的含義和好處以及它們是否適用於其他 shebang?

答案1

如果腳本/path/to/foo以 開頭#!/bin/bash,則執行/path/to/foo arg1 arg2相當於執行/bin/bash /path/too/foo arg1 arg2。如果shebang行是#!/bin/bash -ex,則相當於執行/bin/bash -ex /path/too/foo arg1 arg2。該功能由核心管理。

請注意,shebang 行上只能有一個參數:某些 unice(例如 Linux)僅接受一個參數,因此這#!/bin/bash -e -x將導致 bash 接收單個五字元參數-e -x(語法錯誤),而不是兩個參數-e-x

對於 Bourne shellsh和衍生 shell,例如 POSIX sh、bash、ksh 和 zsh:

  • -e意味著如果任何命令失敗(透過返回非零狀態來指示),腳本將立即終止。
  • -x使 shell 列印執行追蹤。

其他程式可能會理解這些選項,但含義不同。

答案2

它們是傳遞以bash查看help set更多資訊的選項,在本例中:

-x  Print commands and their arguments as they are executed.
-e  Exit immediately if a command exits with a non-zero status.

答案3

我只想提一個更好的——比如更便攜的——替代方案:

#!/usr/bin/env bash

上面的範例用於env查找bash可執行文件,該可執行文件並不總是位於/bin/bash.舊的#!/bin/bash腳本不起作用尼克斯作業系統, 例如。

如果您env按照上面演示的方式使用,則無法提供諸如-eto 之類的參數bash(據我所知)。但你可以這樣做:

#!/usr/bin/env bash
set -e

答案4

使用 啟動腳本,或等效地運行 ,與在腳本中緊跟其行之後插入具有相同的效果。#! /path/to/bash -optionbash -option /path/to/scriptset -option#!

set -x本質上只是為了調試;你不會希望它正常打開的。

其效果set -e比手冊提示的要複雜得多。更準確的描述大致是:

調用後set -e,如果未經測試的命令以非零狀態退出,它將導致 shell 以該退出狀態退出。

我說更確切因為它仍然相當模糊:考慮該命令的情況列表經測試是神秘且難以預測的。不同 shell 之間的確切規則有所不同,甚至同一 shell 的版本之間也會改變。

set -e不是導致 Bash 退出以回應任何命令的非零退出狀態:

  • 之間;或者ifelifthen
  • 之間;或者whileuntildo
  • 下列的!;或者
  • 後面是||or&&&(儘管&對應的waitorfg可能會失敗);或者
  • 後跟|,除非set -o pipefail有效;或者
  • $( ... )當用作命令的一部分時在內部(不是純粹的分配和/​​或重定向,這意味著foo=$( bar )如果失敗就會失敗bar,但local foo=$( bar )不會);或者
  • 在上述適用的複合命令中;或者
  • 在從上述適用的任何地方呼叫的 shell 函數內。

對複合指令和 shell 函數的影響是遞歸的。

由於 shell 本身以非零狀態退出,因此效果可以傳播到子 shell 之外。

!即使忽略反向退出狀態,豁免也適用。

相反,set -e觸發所有其他非零狀態,無論它是否意味著“失敗”或只是“錯誤”。例如,當最初為 0((x++))時,將具有非零「失敗」退出狀態。x

因為它太混亂了,所以有一個學派認為set -e應該避免使用明確檢查所有命令。

或者,如果您仍然想使用set -e,請記住寫!在任何組的前面((arithmetic))

相關內容