Можно ли дублировать дескриптор входного файла и использовать его для записи данных?

Команда ниже создает копию дескриптора входного файла и использует дубликат дескриптора файла для записи данных из команды echo на терминал.

 sh-4.2 $ exec 6 <& 0
 sh-4.2 $ echo "hello"> & 6
 Здравствуйте

Означает ли это, что мы можем писать на терминал с помощью дескриптора входного файла?

Означает ли это, что мы можем писать на терминал с помощью дескриптора входного файла?

Конечно. Вы можете написать на терминал (действительно, любой файл или канал или устройство или сокет, который поддерживает и авторизует запись), используя любой открытый дескриптор файла, который у вас есть. Простейшая версия вашего кода будет такой:

 echo hello >&0 

который, как и следовало ожидать, отправляет «hello \ n» в любой дескриптор файла, на который указывает 0. Если это ваш терминал, пусть будет так.

Это копия моего ответа на аналогичный вопрос о stackoverflow в прошлом году.

Вы можете записать на стандартный ввод своего терминального устройства из-за исторического обычая. Вот что происходит:

Когда пользователь входит в терминал в Unix-подобной системе или открывает окно терминала в X11, дескрипторы файлов 0, 1 и 2 подключаются к терминальному устройству, и каждый из них открывается для чтения и записи . Это имеет место, несмотря на то, что обычно читается только из fd 0 и записывается в fd 1 и 2 .

Вот код из 7-го издания init.c :

 open(tty, 2); dup(0); dup(0); ... execl(getty, minus, tty, (char *)0); 

И вот как это делает ssh :

 ioctl(*ttyfd, TCSETCTTY, NULL); fd = open("/dev/tty", O_RDWR); if (fd < 0) error("%.100s: %.100s", tty, strerror(errno)); close(*ttyfd); *ttyfd = fd; ... /* Redirect stdin/stdout/stderr from the pseudo tty. */ if (dup2(ttyfd, 0) < 0) error("dup2 stdin: %s", strerror(errno)); if (dup2(ttyfd, 1) < 0) error("dup2 stdout: %s", strerror(errno)); if (dup2(ttyfd, 2) < 0) error("dup2 stderr: %s", strerror(errno)); 

(Функция dup2 дублирует arg1 в arg2, сначала закрывая arg2, если это необходимо.)

И вот как xterm делает это:

 if ((ttyfd = open(ttydev, O_RDWR)) >= 0) { /* make /dev/tty work */ ioctl(ttyfd, TCSETCTTY, 0); ... /* this is the time to go and set up stdin, out, and err */ { /* dup the tty */ for (i = 0; i <= 2; i++) if (i != ttyfd) { IGNORE_RC(close(i)); IGNORE_RC(dup(ttyfd)); } /* and close the tty */ if (ttyfd > 2) close_fd(ttyfd);