Автоматическое усечение длинных выходных данных в bash

#bash

#bash

Вопрос:

Возможно ли автоматическое усечение длинных выходных данных в bash?

В идеале я хотел бы определить ограничение, скажем, MAXLINES, и автоматически применять tail -n $MAXLINES к каждой команде, которая выводит на терминал больше строк MAXLINES (но не в других контекстах, например, в каналах, очевидно).

Ответ №1:

Может быть выполнено с помощью PROMPT_COMMAND

 MAXLINES=10
tmp_out=/tmp/$$.output
PROMPT_COMMAND='touch "$tmp_out"; tail -n "$MAXLINES" "$tmp_out" >/dev/stdin; exec >"$tmp_out"'
  

Как это работает

  • tmp_out=/tmp/$$.output временный файл, используемый для хранения выходных данных команды
  • touch "$tmp_out" : создайте пустой файл, если он не существует, чтобы конечная команда не завершилась ошибкой при первом вызове
  • tail -n "$MAXLINE" "$tmp" > /dev/stdin : показать первые максимальные строки выходных данных
  • exec > "$tmp_out" : очистить временный файл и перенаправляет текущие выходные данные процесса (файловый дескриптор 1) в этот файл, на случай, если stderr также может быть перенаправлен в другой файл, подлежащий усечению (например 2> "$tmp_err" ).

Для запуска команды без перенаправления

 exec >/dev/stdin; ... the command
  

или (важен пробел после { )

 { the command;}>/dev/stdin
  

Для извлечения начальных настроек

 unset PROMPT_COMMAND; exec >/dev/stdin
  

Комментарии:

1. Возможно, сначала вы захотите открыть новую оболочку с помощью bash . Если вы хотите обычный вывод, вы можете exit .

2. @Nahuel: очень приятно. Однако, когда вы говорите ls -la | less , например, длинный вывод также усекается, поскольку less не знает, что он должен выводиться на терминал. Есть идеи, как этого избежать?

3. действительно, поскольку хвост выполняется после завершения команды в командной строке, поэтому программа, работающая с tty, не может работать в интерактивном режиме, для восстановления вывода можно выполнить следующее exec >/dev/stdin ; ls -la | less

4. обратите также внимание, что некоторые программы, такие как ls , ведут себя по-разному, когда выводится tty или файл, например, с escape-последовательностью, сравните touch ''$'33''[31mhello'$'33''[0m' и ls *hello* и ls *hello* >/dev/stdin , также ls -a в tty будут отображаться имена файлов в столбцах, тогда как в файле будет отображаться один файл по строке, например ls -a1