Почему tcsh постоянно имеет несколько fd, указывающих на /dev/tty

Почему tcsh постоянно имеет несколько fd, указывающих на /dev/tty

Это на 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, то вижу пять файловых дескрипторов, отличных от std{in, out, err}, указывающих на tty, а 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

Зачем tcshнужно так много файловых дескрипторов, указывающих на tty, и в чем преимущество сопоставления 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/

Связанный контент