Bash
子殼不傳播錯誤,bash 4.4
我在 github 工作流程中有這個
- run: bash --version - name: run postgres run: | set -e shopt -s inherit_errexit export ID=$(docker run \ --publish 5432:5432 \ --network skynet \ --network-alias db.host \ --env-file .github/env/postgres \ --detach ${{ steps.postgres-tag.outputs.data }} ) shell: bash -euET -o pipefail -O inherit_errexit {0}
這是它的執行輸出
GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)
set -e shopt -s inherit_errexit export ID=$(docker run \ --publish 5432:5432 \ --network skynet \ --network-alias db.host \ --env-file .github/env/postgres \ --detach ) shell: /bin/bash -euET -o pipefail -O inherit_errexit {0} env: AWS_DEFAULT_REGION: us-east-1 AWS_REGION: us-east-1 AWS_ACCESS_KEY_ID: *** AWS_SECRET_ACCESS_KEY: *** "docker run" requires at least 1 argument. See 'docker run --help'. docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
使用 bash 5 在 OS X 上進行最小複製
bash-5.0$ export ID=$(docker run) "docker run" requires at least 1 argument. See 'docker run --help'. Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Run a command in a new container bash-5.0$ echo $? 0 bash-5.0$ docker run "docker run" requires at least 1 argument. See 'docker run --help'. Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Run a command in a new container > echo $? # services -> feature/RS2-1228-optimize-build $ ! RC=1 1
但是,shell 沒有退出並出現錯誤。我知道通常一個子shell
$()
不會導致錯誤發生……但我認為該設置shopt -s inherit_errexit
解決了這個問題。我的程式碼中是否缺少某些內容?
對比:
$ bash -e -c 'export a=$(false); echo >&2 "If you see this, the previous command succeeded"' If you see this, the previous command succeeded $ bash -e -c 'a=$(false); echo >&2 "If you see this, the previous command succeeded"'
在您的嘗試中,命令替換中的命令失敗,但包含命令替換的命令成功。
export
如果命令替換是普通命令,包括對內置命令的呼叫,則命令替換的狀態不會影響包含命令的狀態。命令替換的狀態僅在它在賦值中時才重要:賦值命令的狀態是命令中最後一個命令替換的狀態,如果沒有命令替換,則為 0(假設賦值本身沒有錯誤,例如嘗試分配給只讀變數)。為了讓您的腳本在第一個錯誤時停止,您需要啟用
inherit_errexit
並將每個命令替換放在單獨的分配中。它必須是一個簡單的賦值:導出變數必須是一個單獨的命令。$ bash -e -O inherit_errexit -c 'export a=$(false; echo >&2 "If you see this, errexit is off inside command substitution"); echo >&2 "If you see this, the previous command succeeded"' If you see this, the previous command succeeded $ bash -e -O inherit_errexit -c 'a=$(false; echo >&2 "If you see this, errexit is off inside command substitution"); echo >&2 "If you see this, the previous command succeeded"'