我設定了一些主要使用的 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
按照上面演示的方式使用,則無法提供諸如-e
to 之類的參數bash
(據我所知)。但你可以這樣做:
#!/usr/bin/env bash
set -e
答案4
使用 啟動腳本,或等效地運行 ,與在腳本中緊跟其行之後插入具有相同的效果。#! /path/to/bash -option
bash -option /path/to/script
set -option
#!
set -x
本質上只是為了調試;你不會希望它正常打開的。
其效果set -e
比手冊提示的要複雜得多。更準確的描述大致是:
調用後
set -e
,如果未經測試的命令以非零狀態退出,它將導致 shell 以該退出狀態退出。
我說更確切因為它仍然相當模糊:考慮該命令的情況列表經測試是神秘且難以預測的。不同 shell 之間的確切規則有所不同,甚至同一 shell 的版本之間也會改變。
set -e
做不是導致 Bash 退出以回應任何命令的非零退出狀態:
- 之間;或者
if
elif
then
- 之間;或者
while
until
do
- 下列的
!
;或者 - 後面是
||
or&&
或&
(儘管&
對應的wait
orfg
可能會失敗);或者 - 後跟
|
,除非set -o pipefail
有效;或者 $( ... )
當用作命令的一部分時在內部(不是純粹的分配和/或重定向,這意味著foo=$( bar )
如果失敗就會失敗bar
,但local foo=$( bar )
不會);或者- 在上述適用的複合命令中;或者
- 在從上述適用的任何地方呼叫的 shell 函數內。
對複合指令和 shell 函數的影響是遞歸的。
由於 shell 本身以非零狀態退出,因此效果可以傳播到子 shell 之外。
!
即使忽略反向退出狀態,豁免也適用。
相反,set -e
觸發所有其他非零狀態,無論它是否意味著“失敗”或只是“錯誤”。例如,當最初為 0((x++))
時,將具有非零「失敗」退出狀態。x
因為它太混亂了,所以有一個學派認為set -e
應該避免使用明確檢查所有命令。
或者,如果您仍然想使用set -e
,請記住寫!
在任何組的前面((arithmetic))
。