#c #linux #terminal #pipe
#c #linux #терминал #канал
Вопрос:
Недавно я пытаюсь написать простую версию Linux command more
. Для того, чтобы сделать это, мне нужно ввести неканонический режим и отсутствие эха в терминале, чтобы я получал ввод сразу после нажатия клавиши, а терминал не отображал символ, который я ввожу.
Я сделал это, поступив таким образом:
// set the terminal mode
struct termios tm;
tcgetattr(STDIN_FILENO, amp;old);
tm = old;
tm.c_lflag amp;= ~(ICANON | ECHO);
tm.c_cc[VMIN] = 1;
tm.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSADRAIN, amp;tm);
Это работает, когда я использую аргументы типа
more test_file
Но когда я попытался выполнить канал more
с помощью другой команды, такой как
ls /bin | more
Терминал возвращается в канонический режим и режим эха. Почему это происходит?
Комментарии:
1. Проблема в том, что когда вы читаете из канала, он не подключен к терминалу. Если вы хотите иметь возможность считывать входные данные как из канала (через
STDIN_FILENO
), так и из терминала, вы должны открыть терминал специально и настроить и прочитать из этого дескриптора.2. Вы не проверили результаты системных вызовов, и они завершились неудачей, вероятно, из-за ошибки ENOTTY.
3. man7.org/linux/man-pages/man3/ctermid.3.html
4. @Someprogrammerdude И как именно я могу это сделать?
Ответ №1:
Вообще говоря, такие вещи, как more
ожидаются для чтения из stderr
(или иногда, /dev/tty
но stderr
работает лучше). Вместо этого вы включаете терминал stdin
. Это работает не так хорошо.
Комментарии:
1. В программе я считываю нажатие клавиши из
/dev/tty
. Что мне делать?2.В программе я считываю нажатие клавиши из
/dev/tty
. Что мне делать?3. @Rivers Shall: очевидно, что тогда вы также должны использовать tcgetattr и tcsetattr в вашем дескрипторе / dev / tty. Смотрите функцию fileno.