別のユーザーとして特定のコマンドを実行し、実行が完了したら (成功または失敗) すぐにログアウトするスクリプトを作成しました。
-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
はすべて正しい出力を生成しました。ただし、スクリプトを実行しようとするコマンドはすべて、エラーで失敗します。ls
which
bash --version
mkdir
rm
whoami
su user2 -c 'bash --version' # Works
su user2 -c 'bash some-script.sh' # Doesn't work
なぜこのようなことが起こるのか分かりません。そして、このエラーを修正できない理由も分かりません。
答え1
この動作の理由は、の最新バージョンのマニュアル ページに記載されていますsu
。
-c, --command コマンド
を使用してシェルによって呼び出されるコマンドを指定します
-c
。実行されたコマンドは制御端末を持たないこのオプションは、制御 TTY を必要とする対話型プログラムの実行には使用できません。
(強調は筆者による)
ls
、echo
またはなどの基本コマンドを実行すると、制御端末を必要とせずに、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