同じttyに接続したときにzsh記述子10が0/1/2と異なるオフセットにあるのはなぜですか? fd10を閉じてすぐにfd0をコピーすると影響はありますか? Bash では、対応する 255 は fd0/1/2 と同じオフセットを持ち、これはシステムファイルテーブルの同じエントリであることを示します。もしそうなら、zshはなぜシステムファイルテーブルに別のエントリを持ちたいのですか?
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
zsh 6980 codepoet 0u CHR 16,2 0t1266790 749 /dev/ttys002
zsh 6980 codepoet 1u CHR 16,2 0t1266790 749 /dev/ttys002
zsh 6980 codepoet 2u CHR 16,2 0t1266790 749 /dev/ttys002
zsh 6980 codepoet 10u CHR 16,2 0t3349 749 /dev/ttys002
ベストアンサー1
実行する場合:
strace -e open,openat,fcntl,dup,dup2 zsh -f
または、システムのそれに対応する項目を見ると、次のようになります。
openat(AT_FDCWD, "/dev/pts/2", O_RDWR|O_NOCTTY) = 3
fcntl(3, F_DUPFD, 10) = 10
zshはfd 10のttyを再び開いた。
の場合、bash --norc
以下が表示されます。
dup(2) = 3
dup2(3, 255) = 255
bashのfd255はfd2のコピーです。
サイズ/オフセットはttyデバイスには適していません。この値があなたのシステムで何を表すのかわかりませんが、とにかく2つが異なるという事実はzshで説明できます。 fd 10は異なる点を指します(新しい)ファイル説明を開くBashでは、fd 0、1、または2のfd 255は同じものを指します。ファイル説明を開くFD2と同じです。
これは実際に大きな違いをもたらしません。
zshがttyデバイスを再度開く必要がある理由については、次のコード1を参照してください。
/* Make sure the tty is opened read/write. */
if (isatty(0)) {
zsfree(ttystrname);
if ((ttystrname = ztrdup(ttyname(0)))) {
SHTTY = movefd(open(ttystrname, O_RDWR | O_NOCTTY));
気づくPOSIX シェルは、stdin と stderr の両方が端末に移動し、スクリプトが解釈されない場合にのみ対話型です。。
-i オプションがある場合、またはオペランドがなく、シェルの標準入力および標準エラーが端末に追加される場合、シェルは対話式と見なされます。
zshでは、端末に入るためにstderrは必要ありません。
zshのfd 10(実際には9以上の最初の無料fd)は、bashのfd 255(256未満の最初の無料fd)とまったく同じではありません。 zshのラインエディタは通常I / Oと端末の対話に使用されますが、bashはAFAICTジョブ制御ジョブにのみ使用され、readline
入力にはstdinを使用し、入力エコーにはstderrを使用します。 fd0が読んだり使用したりするために開かない場合、zshはそうではありません。正常に動作しません。 fd2は書き込み用に開いていません。
1コードは1990年代半ば2.5以降に変更されました。それまでは、SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty",O_RDWR))
stdinが端末でなくても対話型シェルを持ち、そのfdに他の開かれたファイル記述がないことをお勧めします。実際には、/dev/tty
タスク制御対話の場合、fd 0または2(現在のzshおよびbashで使用されているように)でttyを使用するよりも、セッション制御端末へのポインタを使用する方が正確です。違い。