su -m $USER -c " の外部で終了コードにアクセスする「

su -m $USER -c " の外部で終了コードにアクセスする「

以下のコマンドは、「su」コマンド内に $? を挿入しているため、失敗したかどうかに応じて「0」または「1」を正しく出力します。

sudo su -m $USER -c "./shutdown.sh &> /dev/null; echo \$?"

ただし、次のようにすると:

sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null"; echo $?

コマンド部分が失敗しても、実際の「su」は常に成功するので、常に「0」が出力されます。

サブシェルの終了コードを取得する方法をご存知ですか?

答え1

ほぼ同じ状況を修正しました。これがまだお役に立てば幸いです。そうでない場合は、他の人にも役立つかもしれません。私は sudo ではなく su から始めましたが、sudo は他の単一のコマンドをラップすることを目的としているため、su の終了コードを中継する必要があります。そうでない場合は、以下の修正を sudo レベルにも適用できます。

あなたが指摘したように、主な問題は su がコマンドを正常に実行することです。デフォルトのアクションは、問題なく完了したことを報告し、終了コード 0 を返します。コマンドからの 0 以外の終了コードが予期されていないことや、それに対して何らかの処理を実行する必要があることを「認識」しません。したがって、解決策は、su が最後のコマンドの終了コードを返すようにすることです。これで私の場合はうまくいきました。

su <user_x> -c '<bunch_of_commands>; exit $?'

sudo がうまく動作しない場合は、コマンド全体は次のようになります (確認したいのですが、sudo はインストールされていません)

sudo 'su <user_x> -c \'<bunch_of_commands>; exit $?\'; exit$?'

引用符のネストに注意し、$? が展開されないように注意してください。つまり、二重引用符は使用しないでください。

答え2

コマンド内で戻り値をエコーし​​、コマンド全体を変数に割り当てることで(サブシェルを使用して)外部からアクセスします。

RETVAL=$(sudo su -m $USER -c "./shutdown.sh &> /dev/null; echo \$?")
echo $RETVAL

答え3

常に tmp ファイルを使用することもできます:

$ sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null; echo \$? > /tmp/exit_code"; cat /tmp/exit_code

答え4

これは Zsh/Bash/Bourne シェルで動作します:

$ sudo su -m $USER -c "$BASE/bin/shutdown.sh &> /dev/null"
$ echo $?

ワンライナーで戻りコードを要求したときには戻りコードが利用できないのに、同じことを実行するのに複数行を使用する場合は戻りコードが利用できるのはなぜかわかりません。

関連情報