以下のコマンドは、「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 $?
ワンライナーで戻りコードを要求したときには戻りコードが利用できないのに、同じことを実行するのに複数行を使用する場合は戻りコードが利用できるのはなぜかわかりません。