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

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

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

ш-4.2$ исполнитель 6<&0
sh-4.2$ echo "привет" >&6
привет

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

решение1

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

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

echo hello >&0

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

решение2

Это копия моего ответа нааналогичный вопросна 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);

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