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
, вероятно, вы увидите те файловые дескрипторы, как описано в вопросе.