30

Я использую команду linux 'script' http://www.linuxcommand.org/man_pages/script1.html для отслеживания некоторых интерактивных сессий. Выходные файлы из этого содержат непечатаемые символы, в том числе мои нажатия клавиш возврата.

Есть ли способ привести в порядок эти выходные файлы, чтобы они содержали только то, что отображалось на экране?

Или есть другой способ записи сеанса интерактивной оболочки (ввод и вывод)?

13 ответов13

31

Если вы хотите просмотреть файл, вы можете отправить вывод через col -bp ; это интерпретирует управляющие символы. Тогда вы можете пройти через меньшее, если хотите.

col -bp typescript | less -R

В некоторых системах col не принимает аргумент имени файла, используйте этот синтаксис:

col -bp <typescript | less -R
16
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed

Вот некоторая интерпретация ввода строки в perl:

  • s/pattern//g означает подстановку всей строки (опция g означает сделать всю вещь вместо остановки первой замены) входной строки

Вот некоторая интерпретация шаблона регулярных выражений:

  • \e соответствует специальному управляющему символу "escape" (ASCII 0x1A)
  • ( и ) являются началом и концом группы
  • | означает, что группа может соответствовать одному из N шаблонов. где N моделей
    • [^\[\]] или
    • \[.*?[a-zA-Z] или же
    • \].*?\a
  • [^\[\]] значит
    • соответствует набору символов NOT, где символы не являются [ и ]
  • \[.*?[a-zA-Z] средства
    • сопоставьте строку, начинающуюся с [ затем сделайте не жадный .*? до первого альфа-символа
  • \].*?\a средство
    • сопоставьте строку, которая начинается с ] затем сделайте не жадный .*? пока вы не нажмете специальный управляющий символ, называемый «предупреждающий (колокольный) символ»
2

col-bp обрабатывает возвраты по желанию (AFAIK). Но это искажает последовательности побега цвета. Возможно, было бы хорошо сначала удалить последовательности цветов, а затем обработать пробелы, если это возможно.

Это очень распространенная потребность, и я удивлен, что нет больше решений для этого. Сценарий сеанса чрезвычайно распространен, тогда кто-то должен пересмотреть процедуру. Вы хотите вырезать все мелкие ошибки при наборе и цветовые escape-последовательности, чтобы создать "чистый" сценарий процедуры для дальнейшего использования. Простой текст ASCII предпочтителен. Я думаю, что это то, что подразумевается под "читабельным человеком", и это очень разумная вещь.

2

Для большого количества выходных данных script я бы итеративно взламывал сценарий perl. В противном случае редактирование вручную с хорошим редактором.

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

Например, экран может быть пустым, за исключением Andrew $ , если вы затем набрали rm /* и нажали клавишу Backspace двенадцать раз (гораздо больше, чем нужно), то, что будет показано на экране в конце, зависит от того, какая оболочка была запущена, что ваши текущие настройки stty (которые вы можете изменить во время сеанса) и, возможно, некоторые другие факторы.

Вышесказанное относится к любому автоматизированному способу непрерывного ввода и вывода. Основная альтернатива - делать "снимки экрана" или вырезать и вставлять экран в подходящее время во время сеанса (что я и делаю для руководств пользователя, заметок для дневника и т.д.).

2

Если вам нужно записать ваши команды (например, чтобы потом превратить их в скрипт bash), тогда разумным будет взломать script(1) , а затем запустить его внутри

bash -x

После этого grep выходного файла (обычно "машинопись"), ищущего строки, начинающиеся с «+». Регулярное выражение ^\+ поможет.

2

Ответом на вторую часть моего вопроса является использование средства ведения журнала в gnu screen: ^A H из сеанса рабочего экрана. Документация находится по адресу http://www.gnu.org/software/screen/manual/screen.html#Logging.

2

Я использовал cat filename который удаляет управляющие символы :-)

2

Если вы хотите записать вывод в файл:

col -bp < typescript >>newfile

используйте команду unix2dos для преобразования файла в формат Windows, если хотите

1

https://github.com/RadixSeven/typescript2txt был написан для решения этой проблемы.

Прошло 4 года с тех пор, как я последний раз обновлял / использовал его, но я не помню, чтобы я делал что-то необычное, что не должно работать сегодня.

1

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

сценарий dewtall:

#!/usr/bin/perl
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \r | # Remove extra carriage returns also
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
       1 while s/[^\b][\b]//g;  # remove all non-backspace followed by backspace
    print;
}

Чтобы удалить управляющие символы:

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed
0

Я нашел хороший способ сделать это. В моей системе длинные выходные строки посыпаются символом «^ M» (пробел, за которым следует возврат каретки). Символ «^ M» может быть заменен нулевым символом «^ @», который вообще не отображается при просмотре файла.

Я также фиксирую время, поэтому, чтобы воспроизвести файл идеально, я не могу просто полностью удалить «^ M», используя приведенные ниже команды (потому что скрипт запускает подсчет байтов):

tr '\r' '\0' | sed 's/ \x0//g'

Я запускаю команду сценария следующим образом:

script -t -f session.log 2>timing

Итак, что я делаю потом:

cat session.log | tr '\r' '\0' > typescript 
scriptreplay -t timing | sed 's/ \x0//g'

При первом редактировании (до воспроизведения) сохраняется количество байтов в файле. Второе редактирование (после воспроизведения) избавляет от пробелов в случайных местах. (Обратите внимание, что по умолчанию scriptreplay ищет входной файл с именем "typescript", поэтому я не предоставил его после "синхронизации".)

-1

DOS2UNIX на выходе также сделает свое дело

-2

Еще одно решение - использовать strings которые печатают только печатаемые символы из файла (или из стандартного ввода):

strings -n 1 filename

Опция -n 1 устанавливает минимальную длину последовательностей, которые должны быть сохранены, и, таким образом, гарантирует, что сохраняются даже отдельные печатаемые символы, окруженные непечатными символами.

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

Foo<SOMECONTROLCHAR>Bar

(где <SOMECONTROLCHAR> является управляющим символом или любым другим непечатным символом) будет возвращено как

Foo
Bar

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

Тем не менее, strings отлично справляется с удалением управляющих символов, таких как backspace, упомянутый в вопросе

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .