2010-11-25 2 views
3

Я пытаюсь найти способ вызвать интерактивную программу командной строки, чтобы он вносил ввод как непосредственно с клавиатуры, так и из именованного канала. Моя цель - заставить это работать с MATLAB, но я думаю, что Bash работает так же хорошо, как пример. Поэтому идея состоит в том, чтобы запустить Bash, и как только он будет запущен, я могу вводить команды, использовать стрелку для истории и т. Д., А также отправлять команды именованному каналу. Я оглядывался и играл в это несколько дней, но ничто из того, что я пробовал до сих пор, не сработало.Как вы подключаете клавиатуру и именованный канал к STDIN в Bash?

Например, есть полезная нить в https://serverfault.com/questions/171095/how-do-i-join-two-named-pipes-into-single-input-stream-in-linux, что предлагает делать что-то вроде этого:

mkfifo alt_in 
(tail -f alt_in & cat) | bash 

Это почти то, что я ищу, за исключением того, что если вы пытаетесь использовать Backspace, или клавиши со стрелками оно не работает правильно. (Думаю, это потому, что cat перехватывает нажатия клавиш, которые обычно обрабатываются библиотекой readline в bash?) Есть ли у кого-нибудь другие предложения?

В конечном счете, я хотел бы иметь способ запустить процесс MATLAB, чтобы я мог отправлять команды ему из TextMate, но также взаимодействовать с ним в терминале. Я использую MATLAB для работы, но я не очень люблю его графический интерфейс или редактор.

Редактировать Декабрь 19, 2010

Спасибо за все очень полезные советы! Я хотел подвести итоги этого для всех, кто интересуется. Я заглянул в rlwrap, но так как моя цель заключалась в том, чтобы получить эту работу внутри пакета TextMate, который мог бы использовать любой пользователь, я не решался полагаться на нестандартную утилиту (о которой я должен был упомянуть в первую очередь). Я также проверил на expect и unbuffer вкратце, но, ну, они кажутся довольно сложными, и я просто не обладал способностью погрузиться в это.

screen работал очень хорошо для этого - как предложено ниже, я мог бы открыть терминал, начать screen, начните matlab -nodesktop, и тогда это было возможно иметь TextMate, например, отправить выделенный текст в Matlab с помощью screen -X ... внутри команды TextMate , Недостатки такого подхода, которые я заметил, были следующими:

  1. Отправка блока текста с более чем 1024 символами привела к ошибке из `screen`; Я полагаю, что там где-то есть буфер, который не может держать больше, чем это, но не тратил времени, пытаясь отследить его.
  2. Экран имеет свой собственный буфер прокрутки, что делает панель прокрутки терминала довольно бесполезной. Может быть, есть возможность изменить, как это работает?
  3. Control-A - клавиша команды `screen`; вы не можете использовать его для перехода к началу строки, если вы не перекроете командный ключ.

В то время как я играл с screen, мне пришло в голову, что хотя вопрос, который я задал, касается подключения труб и STDIN и т. Д., Я на самом деле забочусь об этом только в очень конкретном случае: получение текста из TextMate до Терминал. И это побудило меня попробовать сделать это с помощью AppleScript, и на удивление оказалось, что это было проще и надежнее, чем любая другая вещь, которую я пробовал. Создать команду, которая принимает TextMate выделенного текста или текущую строку в качестве входных данных, и содержит

#!/usr/bin/env osascript 

set input_command to do shell script "cat" 

tell application "Terminal" 
    do script input_command in window 1 
end tell 

И это прекрасно работает, до тех пор, как MATLAB находится в самой передней окна терминала. (Также можно найти вкладку «Терминал», на которой запущен MATLAB, я просто исключил это для ясности.)

Мораль этой истории заключается в том, что я должен задать более конкретные вопросы. Еще раз спасибо всем за помощь; Я многому научился от борьбы с этим!

+0

У меня нет времени, чтобы набрать полный ответ, но я могу указать несколько вещей: (1) `cat` на самом деле не перехватывает нажатия клавиш. Оболочка, в которой выполняется этот скрипт, выполняется и выполняет буферизацию строк. Поэтому каждая строка не отправляется в новый экземпляр bash до тех пор, пока вы не нажмете enter, затем он будет отправлен сразу. (2) Принимающий баш может работать не так, как вы ожидаете, поскольку его вход не от терминала, поэтому я считаю, что библиотека readline/ncurses (в зависимости от того, что она использует) будет вести себя по-другому. Короче говоря, вероятно, нет простого способа сделать это отлично. – cdhowie 2010-11-25 05:29:23

ответ

1

Дайте этому попытку:

mkfifo alt_in 
(tail -f alt_in & rlwrap cat) | bash 

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

Некоторые другие вещи, чтобы исследовать:

  • ожидать
  • экрана -x и экран -X

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

screen -ls 

для определения PID сессии screen вы начали.Это будет цифрами в начале строки, которая выглядит следующим образом:

31544.pts-2.hostname  (01/01/2010 01:01:01 PM)  (Attached) 

Теперь вы можете сделать что-то вроде этого:

screen -S 31544 -X stuff $'echo Your ad here.\n' 

, который заставит команду echo быть выполнена на другом Терминал. $'' приводит к интерпретации экранирующих последовательностей в этом случае, давая нам новую строку, поэтому мы можем «нажимать» Введите.

Допустим, мы сделали это:

screen -S 31544 -X stuff $'top\n' 

Теперь top работает. Мы могли бы пойти на этот терминал и нажать q, чтобы уйти, но где это весело?

screen -S 31544 -X stuff 'q' 

Обратите внимание, что на этот раз нам не нужна новая линия.

1

Попробуйте передать данные в bash через unbuffer.

0

Ввод клавиатуры поступает в разные вкусы, называемые «сырой режим», «режим перехвата» и «приготовленный режим».

Необработанный режим, когда ОС передает каждое нажатие клавиши при вводе ее в программу (например, bash).

Кулинарный режим - это то, где ОС буферизует линию и позволяет выполнять простое редактирование, например удаление символов. Когда вы нажимаете RETURN или EOF (обычно Ctrl-D), он отправит строку в программу.

Команда stty позволяет вам определить несколько кодов клавиш, которые интерпретируются как конец строки (RETURN), EOF (Ctrl-D) и множество других.

Cbreak-mode - это полпути, где многие управляющие символы сохраняют свою обычную функцию, но ОС по-прежнему отправляет символы по одному в приложение. Такие программы, как bash, vi, и менее обычно используют этот режим.

Если вы установили свой терминал в необработанный режим, вы больше не сможете использовать клавиатуру, чтобы «вырваться» из него, если только программа, с которой вы работаете, работает.

Ожидать (here или here) может представить интерфейс терминала Bash, так что он все еще думает, что он работает от обычной клавиатуры и по-прежнему будет делать все прохладную Баш редактирование командной строки, которые мы привыкли.

И Expect может считывать ввод с клавиатуры в сыром режиме и в трубе и беспрепятственно передавать ее.

Смежные вопросы