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 tcsh
so 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 tcsh
Prozesse aufgespalten werden, damit sie in die Konsole schreiben bzw. von dort lesen?
Antwort1
tcsh
ist 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 tcsh
Dateideskriptoren verwaltet werden. Im Gegensatz zu bash
bietet 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.h
hat 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 tcsh
von 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 tcsh
Konfiguration (z. B. ~/.login
, ~/.cshrc
/etc/csh.*
) – suchen Sie nach allem, was stdin, stdout, stderr umleitet.
Wenn ich es tcsh
auf 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/