su -c の使用時にエラーがスローされました: bash: このシェルにはジョブ制御がありません

su -c の使用時にエラーがスローされました: bash: このシェルにはジョブ制御がありません

別のユーザーとして特定のコマンドを実行し、実行が完了したら (成功または失敗) すぐにログアウトするスクリプトを作成しました。

-cコマンドを実行するには を使用できると読みましたsu。そこで、次のようなスクリプトを書きました。

#!/usr/bin/env bash

su - user2 -c "echo 'hurray' && exit"

コマンドは実行されますechoが、user2ログアウトしないためログインしたままになります。logoutの代わりにを使用しようとしましたがexit、ログインしたままになります。 コマンドuser1を呼び出してとして実行するスクリプトを として実行suし、完了後にuser2制御を に戻す必要があります。user1

アップデート

自動的にログアウトできるはずでしたが、今回はいくつかのコマンドが実行されていません。例:

コマンド1:

su user2 -c 'echo 1'

出力1:

1

そして、自動的にログアウトします。

コマンド2:

su user2 -c 'bash some-script.sh'

出力2:

bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell

そのため、-cを介して何らかのスクリプトを実行しようとするとsu、常に上記のエラーが表示されます。 、 、 、 などのオプションを使用して多くのコマンドを試しました。これらのコマンド-cはすべて正しい出力を生成しました。ただし、スクリプトを実行しようとするコマンドはすべて、エラーで失敗します。lswhichbash --versionmkdirrmwhoami

su user2 -c 'bash --version'      # Works
su user2 -c 'bash some-script.sh' # Doesn't work

なぜこのようなことが起こるのか分かりません。そして、このエラーを修正できない理由も分かりません。

答え1

この動作の理由は、の最新バージョンのマニュアル ページに記載されていますsu

-c, --command コマンド

を使用してシェルによって呼び出されるコマンドを指定します-c

実行されたコマンドは制御端末を持たないこのオプションは、制御 TTY を必要とする対話型プログラムの実行には使用できません。

(強調は筆者による)


lsechoまたはなどの基本コマンドを実行すると、制御端末を必要とせずに、bash --version出力がストリームに印刷されます。stdout

方法bashが(対話型シェルとして)呼び出されているか、some-script.sh制御端末デバイスを必要とするコマンドが含まれているため、実行するとエラーが'bash some-script.sh'スローされると思われますcannot set terminal process group (-1): Inappropriate ioctl for device

説明

制御端末プロセスの場合、制御端末は、プロセスが開始された端末デバイスです。制御端末は、プロセス グループに信号を送信することができ、Unix オペレーティング システムでジョブ制御が機能するメカニズムです。ジョブ制御により、プロセス グループ内のプロセスをフォアグラウンドまたはバックグラウンドで実行できます。

コマンドの出力には、ps各プロセスの制御端末が表示されます。例:

$ ps

  PID TTY          TIME CMD
 3614 pts/5    00:00:00 bash
31628 pts/5    00:00:00 ps

最近のsuの変更

以前は、su -c対話型シェルを実行していないときに制御端末を起動していました。Ubuntuapt-get changelog loginシステムで実行すると、制御端末の削除がセキュリティ対策として 2012 年 5 月に導入されたことがわかります。

  • su: コマンド実行時に制御端末をドロップすることで発生する可能性のある tty ハイジャックを修正 (CVE-2005-4890)。クローズ: #628843

関連情報