сбой перенаправления

Нет. Терминальные приложения читают ввод с клавиатуры из файла устройства (в Linux, что-то вроде / dev / ttyS0 или / dev / ttyUSB0 ... для последовательного устройства, / dev / pts / 0 для псевдотерминального устройства), соответствующего терминалу с клавиатурой, на которой вы печатаете.

Это устройство не обязательно должно быть управляющим терминалом процесса (или любого другого процесса в этом отношении).

Вы можете выполнить cat / dev / pts / x при условии, что у вас есть разрешение на чтение этого файла устройства, и это будет читать то, что набирается на терминале (если есть) на другом конце.

На самом деле, если это управляющий терминал процесса и процесс не находится в группе процессов переднего плана терминала, процесс обычно приостанавливается, если он пытается прочитать из него (и если он был в процессе переднего плана группа, она получит SIGINT / SIGTSTP / SIGQUIT, если вы отправите ^ C / ^ Z / ^ \ , независимо от того, читает ли процесс из оконечное устройство или нет). Этого бы не произошло, если бы оконечное устройство не было управляющим терминалом процесса (если бы процесс был частью другого сеанса). Вот что такое управляющий терминал . Это предназначено для механизма управления заданиями , реализуемого интерактивными оболочками.Помимо сигналов SIGTTIN / SIGTTOU и SIGINT / SIGTSTP / SIGQUIT, управляющий терминал участвует в доставке SIGHUP при зависании терминала, это также устройство tty, на которое перенаправляется / dev / tty .

В любом случае, это только для терминального ввода: реально, как в оконечном устройстве, подключенном через последовательный кабель, эмулируется, как эмуляторы терминала X11, такие как xterm , которые используют псевдотерминальные устройства, или эмулируются ядром, как виртуальные терминалы в Linux, которые взаимодействуют с процессами с помощью / dev / tty (и поддерживают больше, чем стандартный интерфейс терминала).

Приложения, подобные X-серверу, обычно получают ввод с клавиатуры от драйверов клавиатуры. В Linux используются общие уровни абстракции ввода. X-сервер, в свою очередь, предоставляет механизм событий для передачи событий клавиатуры подключающимся к нему приложениям. Например, xterm будет получать события клавиатуры X11, которые он переводит на запись символов на ведущую сторону псевдотерминального устройства, что переводится в процессы, выполняющиеся «внутри» xterm , считывающие соответствующий символов при чтении с соответствующего псевдотерминального ведомого устройства ( / dev / pts / x ).

Нет такого понятия, как терминальное приложение . То, что мы называем терминальным приложением выше, - это приложения, которые обычно используются в терминале, которые, как ожидается, будут отображаться в терминале и принимать ввод с терминала, такого как vi , и интерактивная оболочка или минус .Но любым приложением можно управлять с помощью терминала, и любое приложение, которое читает или записывает файлы или их stdin / stdout / stderr, можно заставить выполнять ввод-вывод на терминальное устройство.

Например, если вы запустите firefox , приложение, которое подключается к X-серверу для пользовательского ввода-вывода, из оболочки, работающей в xterm , firefox унаследует управляющий терминал от своей родительской оболочки. ^ C в терминале уничтожит его, если он будет запущен оболочкой на переднем плане. Он также будет иметь файловые дескрипторы 0, 1 и 2 (stdin, stdout и stderr), открытые в этом файле / dev / pts / (опять же, как унаследованные от его родительской оболочки). И firefox вполне может в конечном итоге записать на fd 2 (stderr) какие-то ошибки (и если он был помещен в фоновый режим и оконечное устройство было настроено с помощью stty tostop , тогда он получит SIGTTOU и будет приостановлен).

Если вместо этого firefox запускается вашим менеджером X-сессий или менеджером Windows (когда вы щелкаете какой-либо значок firefox в каком-либо меню), он, скорее всего, не получит никакого управляющего терминала и не будет иметь дескриптора файла. подключен к любому (вы увидите, что ps -fp показывает ? как tty и lsof -p не показывает дескриптор файла на / dev / pts / * или / dev / tty * ). Однако, если вы перешли к file: /// dev / pts / , firefox все равно мог бы выполнять некоторые операции ввода-вывода на терминальное устройство.И если он открыл этот файл без флага O_NOCTTY , и если он оказался лидером сеанса, и если у / dev / pts / еще не было подключенного сеанса для него это устройство в конечном итоге станет управляющим терминалом этого процесса firefox .

Дополнительная литература:

Изменить

После вашего edit немного проясняет вопрос и добавляет некоторый контекст.

Из приведенного выше должно быть ясно, что процесс может считывать ввод с любого оконечного устройства, которое ему нравится (кроме управляющего терминала, если процесс не входит в его группу процессов переднего плана), но это не совсем то, что вас здесь интересует.

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

Такие приложения, как tr , получают ввод со стандартного ввода и записывают его на стандартный вывод. Когда stdin / stdout - это tty-устройство с терминалом на другом конце, они оказываются интерактивными в том смысле, что они читают и записывают данные от / к пользователю.

Некоторые текстовые редакторы терминала (например, ed / ex и даже некоторые реализации vi ) продолжают читать вводимые данные из stdin, когда stdin больше не является терминалом, поэтому они могут быть скриптовыми.

Пейджер - это типичное приложение, которому все еще необходимо взаимодействовать с пользователем, даже если его ввод не является терминалом (по крайней мере, когда их вывод все еще идет на терминал). Поэтому им нужен другой канал для оконечного устройства , чтобы принимать вводимые пользователем данные. И вопрос: какое оконечное устройство они должны использовать?

Да, это должен быть управляющий терминал. Как правило, это то, чем должен быть управляющий терминал.Это устройство, которое отправит пейджеру SIGINT / SIGTSTP, когда вы нажмете Ctrl-C / Z, поэтому для пейджера имеет смысл читать другие нажатия клавиш с того же терминала.

Типичный способ получить дескриптор файла на управляющем терминале - открыть / dev / tty , который перенаправляет туда (обратите внимание, что он работает, даже если процесс изменил euid, поэтому он не имеет разрешение на чтение исходного устройства. Это намного лучше, чем пытаться найти путь к исходному устройству (что в любом случае невозможно сделать переносимо)).

Некоторые пейджеры, такие как less или most open / dev / tty , даже если stdin является устройством tty (в конце концов, можно было сделать меньше dev / ttyS0 из эмулятора терминала, чтобы увидеть, что отправляется по последовательному каналу).

Если открыть / dev / tty не удалось, это обычно из-за того, что у вас нет управляющего терминала. Кто-то может возразить, что это потому, что вы были явно отключены от терминала, поэтому не следует пытаться взаимодействовать с пользователем, но есть потенциальные (необычные) ситуации, когда у вас нет управляющего терминального устройства, но ваш стандартный ввод / stdout по-прежнему является устройством tty, и вы все равно хотите взаимодействовать с пользователем (например, аварийная оболочка в initrd).

Таким образом, вы можете вернуться к взаимодействию с пользователем со стандартного ввода, если это терминал.

Кто-то может возразить, что вы хотите проверить, что stdout является оконечным устройством и , что он указывает на то же оконечное устройство, что и управляющее (для учета вещей, которые делают человек - l / dev / stdin dev / ttyS0> / dev / ttyS1 , например, если вы не хотите, чтобы пейджер был создан man для взаимодействия с пользователем), но это, вероятно, не стоит особенно беспокоиться учитывая, что это не так просто сделать переносно. Это также может нарушить другие странные варианты использования, которые ожидают, что пейджер будет интерактивным, пока stdout является терминальным устройством.

1
26.02.2017, 21:11
1 ответ

Основная проблема, похоже, связана с & в URL после «Радио» и перед «режимом». Он завершает команду snapserver и начинает новую (присвоение переменной, вывод которой перенаправляется), оставляя вывод snapserver не перенаправленным.

Согласно вашему комментарию, измененная команда:

snapserver -s 'pipe:///tmp/snapfifo?name=Radio&mode=read' &>/dev/null & 
1
27.01.2020, 23:46

Теги

Похожие вопросы