su -m $ USER -c“ <cmd>”の外部で終了コードにアクセスする


8

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

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

ただし、これを行う場合:

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

コマンド部分が失敗した場合でも、実際の「su」は常に成功するため、常に「0」を出力します。

サブシェルの終了コードを取得する方法はありますか?

回答:


7

ほぼ同じ状況を修正しました。それでもおそらくそれが他の人ではないとしても、それがあなたを助けることを願っています。私はsudoではなくsuから始めましたが、sudoは他の1つのコマンドをラップすることを目的としているため、実際には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

0

あなたはいつもtmpファイルを使うことができます:

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

ええ、これは今私がやっていることですが、私はtmpファイルに依存しないことを望んでいました。
Nick

0

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

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

1行で要求したときに戻りコードが利用できない理由はわかりませんが、複数の行を使用して同じことを行うときに利用できます。


これは実際には正しくありません。"su -m $ USER -c <cmd>"は、その中の実際のコマンドが成功しなくても常に成功するため、これは常にゼロを返します。
Nick

1
@Nick-ここで動作します。あなたの出力は何ですか?sudo su -m zero2cx -c "/bin/false &> /dev/null"システムのユーザー名で試してください。$?「1」でなければなりません。
zero2cx 2012

うん、私自身のユーザー名では、期待どおりに「1」を返します。しかし、これを使用して、rootや他のユーザーではなく、独自のユーザーを介してアプリを実行しようとしています。
ニック

@Nick- $ USER=appusername希望どおりにsetで動作するはずです。実際のユーザー名を使用しないでくださいappusername。意図したものを使用してください。それはうまくいくはずです、私にとってはうまくいきます。
zero2cx 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.