Warum hat tcsh ständig mehrere FDs, die auf /dev/tty verweisen?

Warum hat tcsh ständig mehrere FDs, die auf /dev/tty verweisen?

Dies ist auf Ubuntu 16.04, mit bash 4.3.42 und tcsh 6.19

Wenn ich eine virtuelle Konsole öffne, die nicht von X verwendet wird, und Bash ausführe, sehe ich stdin, stdout, stderr und (anscheinend) einen dedizierten Dateideskriptor für das TTY.

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

Wenn ich tcsh verwende, sehe ich fünf Dateideskriptoren, die nicht vom Typ „std{in, out, err}“ sind und auf das TTY verweisen, und alle std{in, out, err} sind auf abgebildet /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

Warum sind tcshso viele Dateideskriptoren erforderlich, die alle auf das TTY verweisen, und welchen Vorteil bietet es, 0, 1 und 2 auf zuzuordnen /dev/null? Würde das nicht einfach bedeuten, dass etwas mehr Buchführung erforderlich ist, wenn tcshProzesse aufgespalten werden, damit sie in die Konsole schreiben bzw. von dort lesen?

Antwort1

tcshist anders organisiert als bash(keine Überraschung). Beide sind alt und voller interessanter Eigenheiten für den aufmerksamen Leser.

Dieser Unterschied liegt an der Art und Weise, wie tcshDateideskriptoren verwaltet werden. Im Gegensatz zu bashbietet es dem Skriptautor keine Möglichkeit, nummerierte Dateideskriptoren zu manipulieren. Die Entwickler fanden es praktisch, ihre Dateideskriptoren nachziehen umdie Standard-Streams in einen "gespeicherten" Bereich (nicht von echten Skripten verwendet), und beim Ausführen von BefehlenDuplikatediese zu Befehlen (also zu einem Unterprozess) undschließtsie, wenn die Befehle abgeschlossen sind.

Im Quellcodesh.hhat diesen Brockenwas die Verwendung dieser Datei-Deskriptoren erklärt:

/*
 * 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 */

Für beide Shells gibt es mehrere Links zum selben „echten“ Gerät /dev/fd(zumindest für Linux), da der Pseudoterminaltreiber entsprechend organisiert ist.

Sie erhalten übrigens ein anderes Ergebnis, wenn Sie es tcshvon einer anderen Shell aus ausführen. Wenn Ihre Standard-Shell jedoch ist tcsh, werden Sie wahrscheinlich die Dateideskriptoren sehen, die in der Frage beschrieben sind.

Antwort2

Dies liegt mit ziemlicher Sicherheit an Ihrer tcshKonfiguration (z. B. ~/.login, ~/.cshrc /etc/csh.*) – suchen Sie nach allem, was stdin, stdout, stderr umleitet.

Wenn ich es tcshauf meinem System ausführe, erhalte ich:

$ 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/

verwandte Informationen