同じttyに接続したときにzsh記述子10が0/1/2と異なるオフセットにあるのはなぜですか?それはそんなに重要なのか?

同じttyに接続したときにzsh記述子10が0/1/2と異なるオフセットにあるのはなぜですか?それはそんなに重要なのか?

同じ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を使用するよりも、セッション制御端末へのポインタを使用する方が正確です。違い。

おすすめ記事