Вопрос или проблема
Я только что запустил задачу, которая занимает несколько часов, и забыл перенаправить этот текст в текстовый файл.
псевдокод:
echo [previous text output] > OutputHistory.txt
Кроме того, я не могу просто “скопировать и вставить” то, что было в моем терминале, потому что 1) дисплей опускает важные символы форматирования, такие как “\t”, и 2) я мог закрыть окно терминала.
Возможно ли это с помощью каких-либо команд Unix?
Это невозможно в общем случае. Как только приложение выдало какой-то вывод, единственное место, где этот вывод хранится, — это память терминала. Чтобы привести экстремальный пример, если это 1970-е годы, терминал — это принтер с жёсткой копией, вывод не вернётся обратно в компьютер, пока кто-то не введёт его вручную.
Если вывод всё ещё находится в буфере прокрутки вашего эмулятора терминала, вы можете его вернуть, но как это сделать, зависит от терминала, стандартного способа нет. Табуляции могут быть или не быть преобразованы в пробелы на этом этапе. Может ли информация о форматировании (цвета, жирный шрифт и т. д.) быть извлечена и в каком формате, зависит от терминала. В большинстве терминалов нет простого или надёжного способа определить, где начался и закончился вывод команды.
Если вы планируете заранее, вы можете записать вывод команды прозрачно с помощью script
. Запуск script mycommand.log mycommand
может отличаться от mycommand 2>&1 | tee mycommand.log
, потому что с script
команда всё ещё записывает в терминал.
Компромисс заключается в том, чтобы всегда запускать команды с долгим выполнением внутри screen
или tmux
. Оба имеют способ выгрузки буфера прокрутки в файл, а также они позволяют отключиться от сеанса, не прерывая выполнение программы, и подключиться повторно позже.
Только если приложение терминала где-то сохраняло необработанный вывод в файл, как это делает, например, iTerm
с включённым логированием, или какое-то другое приложение для логирования (autoexpect(1)
или эквивалент) сохраняло вывод, будет доступен этот необработанный вывод. Обычно это должно быть настроено заранее и требует управления, например, если кто-то оставит yes
работающим на некоторое время, затем — опа! — куда делось место на диске?
Я начал использовать tmux исключительно для этой функции. Если вы используете графический интерфейс терминала, вы, вероятно, можете задать команду, когда начнёте новую панель (часто это делается в разделе “Профили”).
У меня настроен запуск tmux new-session zsh
(раньше я настраивал tmux на использование общего сеанса — и возможно, сделаю это снова — но это пока излишне).
Затем вы можете использовать tmux capture-pane -
, чтобы получить текущее содержимое экрана, или tmux capture-pane -S -10000 -
, чтобы получить 10 тысяч строк до начала экрана.
На самом деле, я сделал небольшой гист, называемый tmux-result, который разбирает это (для моей командной строки) и показывает результат последней (или n-ной) команды. Я использую ---
для строк моего приглашения, а для вашего скрипта потребуется использовать что-то другое.
.
Ответ или решение
Чтобы понять, как можно восстановить предыдущий вывод текста из терминала, следует рассмотреть несколько аспектов работы командной строки и терминала в Unix-системах. В случае, когда вы запустили длительную задачу и не сохранили вывод в файл, это может вызвать значительное количество неудобств, особенно если вы уже закрыли терминал. Однако существует несколько способов, которые могут помочь предотвратить такую ситуацию в будущем, а также некоторые тактики для восстановления данных, если вы все еще можете открыть использовавшуюся сессию.
Теория
Каждый вывод в терминале отображается и управляется терминальным эмулятором, который имеет определенное количество строк в буфере прокрутки, где временно хранятся данные. Когда вы закрываете терминальное окно, этот буфер обычно теряется, что затрудняет восстановление информации. Кроме того, терминалы не хранят форматирование, такое как табуляции ("\t") или цвета, если это не было предварительно настроено.
Одним из способов записи вывода является использование команды script
, которая создает журнал сеанса в текстовом файле. Синтаксис достаточно прост: script имя_файла
, после чего выполняются команды, чья работа нуждается в записи.
Пример
Предположим, вы запускаете долгий процесс, например: ./my_long_task.sh
. Вместо прямого выполнения этой команды вы можете использовать:
script my_output.log
./my_long_task.sh
exit
Файл my_output.log
будет содержать полный необработанный вывод вашего процесса. Это полезно, если необходимо сохранить специфику форматирования и применяемых цветовых схем.
Применение
Отличный подход для управления длинными и ресурсозатратными задачами — использование утилит screen
или tmux
. Эти инструменты позволяют управлять многооконными сессиями и включают функцию сохранения буфера на диск:
-
Tmux: Вы можете записать вывод текущего и предыдущих выполненных команд, используя функции захвата панели. Например, командой
tmux capture-pane -S -10000 > captured_output.txt
вы захватите последние 10,000 строк из буфера и сохраните их в файлcaptured_output.txt
. -
Screen: В
screen
можно использовать командуhardcopy
или настроить автозапись сессии для автоматического сохранения вывода.
Еще одним решением является использование терминальных эмуляторов с функцией записи журнала, таких как iTerm2 на macOS, в котором можно включить автоматическую запись всех сессий, что позволяет позже просмотреть сохраненные логи.
Если же журналы не были заранее сконфигурированы, и окно терминала закрыто, возможности восстановления вывода отсутствуют. В таком случае единственным решением может быть повторный запуск процесса с использованием вышеуказанных методов или перегруппировка данных, которые все же можно восстановить из других источников.
Для ситуаций, когда крайне необходимо сохранить все выводы сессий, рекомендуется сразу запланировать работу с утилитами, способными записывать весь системный вывод (например, fs/legalcompliance security mechanisms или dual-logging через journald).
Заключение: ввод прозрачных методов управления выводом команд в ваш рабочий процесс обеспечит не только сохранение результатов выполнения задач, но и упростит анализа проблем, возникающих в ходе работы. Обязательно учитывайте возможность случайного использования ресурсоемких процессов, могущих заполнить диск данными, и планируйте грамотное время проведенное в консоли сессиях.