tcsh が常に /dev/tty を指す複数の fd を持つのはなぜですか?

tcsh が常に /dev/tty を指す複数の fd を持つのはなぜですか?

これはUbuntu 16.04、bash 4.3.42、tcsh 6.19上で実行されています。

X で使用されていない仮想コンソールを開いて bash を実行すると、stdin、stdout、stderr、および tty 専用のファイル記述子が表示されます (どうやら)。

$ cd /dev/fd
$ ls
0 1 2 255
$ ls -al .
... .
... ..
... 0 -> /dev/tty3
... 1 -> /dev/tty3
... 2 -> /dev/tty3
... 255 -> /dev/tty3

tcsh を使用している場合、tty を指す 5 つの非 std{in, out, err} ファイル記述子が表示され、std{in, out, err} はすべて にマップされます/dev/null

% cd /dev/fd
% ls -al
... .
... ..
... 0 -> /dev/null
... 1 -> /dev/null
... 15 -> /dev/tty3
... 16 -> /dev/tty3
... 17 -> /dev/tty3
... 18 -> /dev/tty3
... 19 -> /dev/tty3
... 2 -> /dev/null

なぜ、tcshtty を指すファイル記述子がこれほど多く必要なのでしょうか。また、0、1、2 を にマッピングする利点は何でしょうか。プロセスをフォークしてコンソールに書き込んだり、コンソールから読み取ったりする/dev/nullときに、少しだけ記録が必要になるだけではないでしょうか。tcsh

答え1

tcshは(驚くことではありませんが)とは構成が異なりますbash。どちらも古く、注意深く読む人にとっては興味深い奇抜な点が満載です。

tcshこの違いは、がファイル記述子を管理する方法によるものです。とは異なりbash、スクリプト作成者に番号付きファイル記述子を操作する方法を提供していません。開発者は、ファイル記述子を次のように整理すると便利だと考えました。動く標準ストリームは「保存された」領域(実際のスクリプトでは使用されない)に保存され、コマンドを実行すると、重複これらをコマンド(つまりサブプロセス)に割り当て、閉じるコマンドが完了したらそれらを実行します。

ソースコードでは、sh.hこの塊があるこれらのファイル記述子の使用法を説明します。

/*
 * The shell moves std in/out/diag and the old std input away from units
 * 0, 1, and 2 so that it is easy to set up these standards for invoked
 * commands.
 */
#define FSAFE   5               /* We keep the first 5 descriptors untouched */
#define FSHTTY  15              /* /dev/tty when manip pgrps */
#define FSHIN   16              /* Preferred desc for shell input */
#define FSHOUT  17              /* ... shell output */
#define FSHDIAG 18              /* ... shell diagnostics */
#define FOLDSTD 19              /* ... old std input */

/dev/fdどちらのシェルでも、擬似端末ドライバがこのように構成されているため、同じ「実際の」デバイスへのリンクが複数存在します(少なくとも Linux の場合)。

ちなみに、tcsh別のシェルから実行すると、異なる結果が得られます。ただし、デフォルトのシェルが の場合はtcsh、質問で説明されているように、ファイル記述子が表示される可能性があります。

答え2

これはほぼ間違いなくtcsh設定の問題です (例~/.login: ~/.cshrc /etc/csh.*) - stdin、stdout、stderr をリダイレクトするものを探してください。

tcsh私のシステムで実行すると、次のようになります:

$ tcsh
> ls -lF /dev/fd/
total 0
lrwx------ 1 cas cas 64 Jun 26 13:28 0 -> /dev/pts/29
lrwx------ 1 cas cas 64 Jun 26 13:28 1 -> /dev/pts/29
lrwx------ 1 cas cas 64 Jun 26 13:28 2 -> /dev/pts/29
lr-x------ 1 cas cas 64 Jun 26 13:28 3 -> /proc/16570/fd/

関連情報