
学習TLDPの高度なBashスクリプトガイドDebian 9のbash 4.4.12では、ttyとptsの次のシェル出力を再設定できません。
bash$ lsof -a -p $$ -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 363 bozo 0u CHR 136,1 3 /dev/pts/1
bash 363 bozo 1u CHR 136,1 3 /dev/pts/1
bash 363 bozo 2u CHR 136,1 3 /dev/pts/1
bash$ exec 2> /dev/null
bash$ lsof -a -p $$ -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 371 bozo 0u CHR 136,1 3 /dev/pts/1
bash 371 bozo 1u CHR 136,1 3 /dev/pts/1
bash 371 bozo 2w CHR 1,3 120 /dev/null
2番目のコマンドを実行するたびに、シェルプロンプトが消え、すべてのキーボード入力の表示が停止しますが、コマンドを実行して出力を表示することもできます。なぜそんなことですか?
答え1
これは、シェルの標準エラーをリダイレクトしたためです。
標準によると、POSIX準拠のシェルはここに対話型プロンプトを作成する必要があります。
これボン覇権、ガボボン、(ダーバンそしてFreeBSD)93 コーエン、MirBSDコーエン、(FreeBSD、OpenBSD、ダーバン)コーエンPD、(FreeBSDそしてダーバン)アルムキスト、そして渡辺シェルはそれに準拠し、対話型プロンプトを標準エラーに書き込みます。あなたはそれらすべての時期的に適切な行動が不足していることがわかります。
しかし、入力をエコーしない動作はより複雑です。
- Debian PD Korn、Debian Almquist、Heirloom Bourne シェルは独自のラインエディタを実装していませんが、カーネルのターミナルラインルールで提供されるラインエディタを使用しています。入力が標準入力としてエコーされるのを見ることができます。
- Watanabe、(FreeBSD 93)Korn、および(Debian 93)Kornシェルは独自の行エディタを実装しています。返品編集中の入力行を(再)表示するときに標準エラーに書き込みます。ただし、端末にエコーが表示されます。存在するコマンドを実行する前
exec
および(標準エラーはもはや端末装置ではないため)もう一度閉じることができませんでした。次の入力に対してラインエディタが呼び出されたとき。したがって、シェルラインエディタの入力エコーがリダイレクトされた標準エラーに移動しても、ターミナルラインルールによって入力された追加の入力を見ることができます。さらに、ラインエディタは、追加の端末サイズの変更を認識しないなど、微妙な方法でバグを発生させます。 /dev/tty
MirBSD Korn、(FreeBSD PD)Korn、および(OpenBSD PD)Kornシェルは、編集された行を標準エラーに(再)表示しますが、他のファイル記述子を直接開き、端末エコーなどの内容を制御する独自の行エディタを実装します。それら成功次の入力用にラインエディタを呼び出すときは、エコーをオフにしてください。これによりいいえ入力時に行エディタでエコーされた追加入力を表示するまたはターミナルライン規律。- Bourne AgainおよびFreeBSD Almquistシェルは、編集された行を標準エラーに(再)表示できる独自の行エディタを実装しています。入力する端末エコーなどを制御します。それら成功次の入力用にラインエディタを呼び出すときは、エコーをオフにしてください。これによりいいえ入力時に行エディタでエコーされた追加入力を表示するまたはターミナルライン規律。
これビジーボックスアルムキストそしてジこれに関して、シェルはPOSIXと互換性がありません。彼らはすべて独自のラインエディタを実装しています。これらの両方を使用すると、この付録で発生すると思われる動作を確認できます。
- BusyBox Almquistシェルのラインエディタは、入力エコーに標準出力を使用します。返品プロンプトを書く場所です。標準エラーリダイレクトの影響を受けません。ただし、標準出力をリダイレクトすると効果が得られます。標準入力を使用して端子サイズの変化を認識します。
- Zシェルは、ZLEを実行する端末デバイスを見つけようとします(明示的に開くまでを含む)
/dev/tty
。起動時にファイル記述子を端末デバイスにコピーします。その後、ZLEはそれを使用します。すべて;入力された入力をエコーするために使用されます。読むインタラクティブなプロンプトを作成し、ターミナルエコーをオンまたはオフにするための入力を入力しました。したがって、ZLEは標準エラー、出力、または入力の後続のリダイレクトに影響されません。必要に応じて、3つすべてを/dev/null
byにリダイレクトできます。Zexec
シェルは引き続きインタラクティブにメッセージを表示して入力を受け取ります。
(これトンプソンexec
シェルは、シェルコマンドメカニズムが発明される以前からサポートされていません。 )
この付録が間違っていると著者Stéphane Chazelasに文句を言わなければ修正することができます。
追加読書
- 」シェル変数」。 シェルとユーティリティ。基本仕様。 IEEE 1003.1:2017。グループを開きます。 2017.
- https://unix.stackexchange.com/a/299440/5132