2014-06-28 4 views
2

Как я могу захватить ввод/вывод скрипта в реальном времени (например, с tee), но по очереди вместо символа? Моя цель - захватить ввод, введенный в интерактивные подсказки скрипта, только после завершения обработки и последующего завершения обработки (после нажатия клавиши RETURN).Bash: как дублировать ввод/вывод из интерактивных скриптов только в полных строках?

В частности, я пытаюсь создать сценарий оболочки для ssh, который создает timestamped журнал команд, используемых на удаленных серверах. The script, который использует тройник для перенаправления вывода для фильтрации, работает хорошо, но перенаправленный вывод становится беспорядочным, когда я использую клавишу backspace или клавиши вверх/вниз для прокрутки моей удаленной истории. Например: service test stopexitservice test stopart или cd ..logs[1Pls -al.

Возможно, есть способ захватить прокрутку и перенаправить терминал, как с тройником?

Обновление: Я нашел character-based cleanup solution, который делает то, что я хочу большую часть времени. Тем не менее, я все еще надеюсь на ответ на этот вопрос (который вполне может быть ответом msw, что это очень сложно сделать).

+0

Попробуйте этот ответ от unix.stackexchange.com: http://unix.stackexchange.com/questions/ 14684/remove-control-chars-including-console-codes-colors-from-script-output. Однако вам лучше использовать историю bash на удаленной машине. – rici

+0

Поскольку я так часто подключаюсь к множеству разных удаленных серверов, мне нужен автоматический способ ведения журналов локально. Один из ответов в вашей ссылке обрабатывает завершение обратного пробела, но не завершение команды вверх/вниз, что приводит к журналу, например, «service test stopexitservice test stopart» при прокрутке через команды «exit», «stop service stop» и ' (даже если я фактически не использую эти команды). Однако, спасибо! – Oleg

+0

Создайте новый файл истории (с отметками времени) для каждого сеанса входа в систему. Удостоверьтесь, что он обновляется часто. Напишите небольшой crontask, который перемещает файлы истории (с sftp) в локальный репозиторий. Возможно, поможет rsync. Если необходимо, напишите обертку ssh, которая записывает, к каким удаленным компьютерам вы подключились (но тогда вам нужно избегать ssh с удаленной машины.) Еще одна опция: использовать sshfs для хранения файлов истории на вашем локальном компьютере. – rici

ответ

1

В мире Unix существуют два основных режима обработки ввода с клавиатуры. Они известны как «сырые», в которых символы передаются от терминала к программе чтения по одному за раз. Это режим, который будут использовать редакторы (и такие), потому что редактор должен немедленно реагировать, когда вы нажимаете клавишу.

Другая терминальная дисциплина называется «приготовленной», которая представляет собой линейное поведение, которое вы считаете линейным вводом строки, когда вы получаете обратное пространство, и команда не выполняется до тех пор, пока вы не нажмете return. Ssh должен принимать ваши данные в сыром режиме по-символу, потому что он не знает, что работает на другой стороне. Например, если вы используете редактор с дальней стороны, он не может дождаться возврата перед отправкой нажатия клавиши. Таким образом, как некоторые предположили, захват истории оболочки на дальней стороне является единственным разумным способом получить командно-командную запись команд bash, которые вы набрали.


Я упрощен для ясности; на самом деле большинство установок bash принимают входные данные в режиме raw, потому что они позволяют редактору изменять команду. Например, Ctrl-P прокручивает историю команд или Ctrl-A переходит в начало строки. И bash должен быть в состоянии получить эти ключи в момент их ввода, не дожидаясь возврата.

Это еще одна причина, что захват на местной стороне неприятно сложно: если вы захватите локальную сторону, поток будет заполнен Backspaces и все команды редактирования bash. Чтобы получить подлинную транскрипцию того, что действительно выполняется удаленной оболочкой, вам нужно проанализировать поток символов, как если бы вы были удаленной оболочкой. Там также проблема, если вы запускаете что-то вроде

vi /some_file/which_is_on_the_remote/machine 

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

Немногие вещи, связанные с компьютерами, невозможны; получение чистого ввода с локальной стороны вызова ssh действительно очень тяжело.

+0

Благодарим вас за отличное объяснение. Теперь я думаю, что моя лучшая надежда состоит в том, чтобы каким-то образом захватить прокрутку терминала. Это так же сложно? – Oleg

+0

Будет ли прокрутка прокрутки лучше всего задаваться как отдельный вопрос? – Oleg

+0

Принято - я думаю, что «нет способа» - это ответ :). – Oleg

0

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

17:00$ cp important_file important_file.bak 
17:15$ rm important_file 

и через два дня вы пытаетесь выяснить, является ли important_file.bak должен иметь содержимое, предназначенные или нет. Учитывая этот журнал, вы не можете ответить на этот простой вопрос. Даже если у вас была последовательность

16:58$ cat important_file 
17:00$ cp important_file important_file.bak 
17:15$ rm important_file 

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

+0

Сразу же, цель сценария - иметь приблизительный отчет о том, как я трачу свое время. 1) У меня есть автоматическая система отслеживания времени, которую я использую для выставления счетов, а сеансы ssh в настоящее время устойчивы к протоколированию. 2) Было бы неплохо рассказать моим клиентам, что я сделал со своими серверами (JUST IN CASE), даже если у них нет надлежащей регистрации на их конце. По крайней мере, я думаю, что это хорошая практика в принципе. Однако у вас есть хорошая идея о выходе. Скрипт ограничен только определенными видами использования. – Oleg

0

Для очень сходной цели я использую GNU screen, которые предлагают возможность записывать все, что вы делаете в сеансе оболочки (INPUT/OUTPUT). Журнал создает также приходит с нежелательными символами, но я убираю их с Perl:

perl -ne 's/\x1b[[()=][;?0-9]*[0-9A-Za-z]?//g;s/\r//g;s/\007//g;print' < screenlog.0

Я надеюсь, что это помогает.

Некоторые особенности screen: http://speaking-my-language.blogspot.com/2010/09/top-5-underused-gnu-screen-features.html

сайта я нашел жемчужно-Oneliner: https://superuser.com/questions/99128/removing-the-escape-characters-from-gnu-screens-screenlog-n

+0

Спасибо за подсказку, но экран, похоже, имеет ту же проблему с завершением вверх/вниз. Я записал сеанс с C-a H, выгруженный вверх и вниз в моей истории команд, и получил результат: 'test [2Plsasastest [K'. Ни одна из этих команд на самом деле не использовалась в моей сессии, просто выгружалась. – Oleg

+0

Я также замечаю, что на экране есть функция дампа прокрутки, но как можно использовать для вывода строки за строкой в ​​реальном времени? Может быть, разница между прокрутками каждую секунду? – Oleg

+0

Я не думаю, что вы сможете вставлять временную марку по очереди, но каждую минуту вы можете сбросить отметку времени: http://aperiodic.net/screen/commands:logtstamp – Tiago