サブシェルがエラーを伝播しない、bash 4.4

サブシェルがエラーを伝播しない、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

ただし、シェルはエラーで終了しません。私は通常、サブシェルが$()エラーを引き起こさないことを知っていますが、この設定は問題shopt -s inherit_errexitを解決すると思います。私のコードに欠けているものはありますか?

ベストアンサー1

比較:

$ 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"'

おすすめ記事