Команда ниже создает копию дескриптора входного файла и использует дубликат дескриптора файла для записи данных из команды 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);