Shell

儘管語法錯誤,Shell 腳本仍返回 0 exit_status

  • May 25, 2021

考慮這個腳本:

#!/bin/sh

foo=1
if [[ ! -z $foo ]]; then
   echo abc
fi

它使用 Bash 語法

$$ [ … $$] 當我在 Ubuntu(破折號)上使用預設 shell 執行它時,它不起作用(如預期的那樣)。但是,它的返回碼仍然為零。

$ ./tmp.sh
./tmp.sh: 4: ./tmp.sh: [[: not found
$ echo $?
0

如果我不能依賴退出程式碼,如何在腳本中檢測到這種錯誤?

讓我先解釋一下為什麼會發生這種情況。POSIX Shell 命令語言規範 說:

if 命令的退出狀態應該是執行的 then 或 else 複合列表的退出狀態,如果沒有執行,則為零。

因為在您的情況下,then部分未執行並且沒有else 退出狀態為 0。如果您使用 Bash 執行此腳本,它也將為 0,因為man bash它說:

  if list; then list; [ elif list; then list; ] ... [ else list; ] fi

         The if list is executed.  If its exit status is zero,
         the then list is executed.  Otherwise, each elif list is
         executed in turn, and if its exit status is zero, the
         corresponding then list is executed and the command
         completes.  Otherwise, the else list is executed, if
         present.  The exit status is the exit sta‐ tus of the
         last command executed, or zero if no condition tested
         true.

如果我不能依賴退出程式碼,如何在腳本中檢測到這種錯誤?

我能想到的方法有兩種:

  • 如果您可以修改腳本,則將else部分添加到 if 構造中:
 #!/bin/sh

 foo=1
 if [[ ! -z $foo ]]; then
     echo abc
 else
     echo not true
     exit 1
 fi
  • 如果您從某人那裡得到 if 並且您不願意修改它,請在sh模式下使用 shellcheck 靜態分析器來查找程式碼中可能存在的錯誤並將它們報告給作者:
 $ shellcheck -s sh dash-exit-status.sh

 In dash-exit-status.sh line 4:
 if [[ ! -z $foo ]]; then
    ^-------------^ SC2039: In POSIX sh, [[ ]] is undefined.
       ^-- SC2236: Use -n instead of ! -z.

 For more information:
   https://www.shellcheck.net/wiki/SC2039 -- In POSIX sh, [[ ]] is undefined.
   https://www.shellcheck.net/wiki/SC2236 -- Use -n instead of ! -z.

基本上,這對我來說是一個錯誤,因為不應該在應該執行的腳本中使用非 POSIX 功能,/bin/sh 這些功能可能但不一定是 Bash 的符號連結。

引用自:https://unix.stackexchange.com/questions/650942