Удалить цвет и перенаправить выход скрипта bash изнутри - PullRequest
0 голосов
/ 13 февраля 2020

У меня простой вопрос, как я могу перенаправить все выходные данные скрипта bash в файл и терминал и удалить цвет символов из скрипта сам?

Я не могу найти ответ, который соответствует всем моим потребностям.

До сих пор я пытался tee для вывода в файл и на терминал, в сочетании с 2>&1, чтобы получить stederr и stdout, sed для удаления цветных символов и всего этого с помощью exec, чтобы сделать это из моего скрипта, но это не работает, я получаю только цветные логи в терминал и ничего в файле.

#!/usr/bin/env bash
exec 2>&1 | sed -r 's/\x1b\[[0-9;]*m//g' | tee script.logs

python somepython.py
python someotherpython.py

Здесь скрипты python производят цветные выводы.

Я хочу записать их на терминал (нетронутый) и в файл (без цвета). В действительности в моем скрипте bash происходит гораздо больше, чем в этих двух скриптах python, поэтому я хочу глобально перенаправить вывод моего скрипта bash, а не просто конвейер после каждого скрипта python.

Таким образом, я использовал exec, потому что я, хотя и разрешил перенаправлять всю продукцию, производимую скриптом.

Заранее благодарен за любые советы и помощь,

PS: Я Я не хочу цветных журналов в файле, но в терминале мне все равно, нужно ли это делать, чтобы журналы не окрашивались в файл.

1 Ответ

2 голосов
/ 13 февраля 2020

Вы можете поместить все свои звонки в фигурную группу и перенаправить весь лот, например:

#!/usr/bin/env bash
{
  python somepython.py
  python someotherpython.py
} 2>&1 | sed -r 's/\x1b\[[0-9;]*m//g' | tee script.logs

Таким образом, все выходные данные stdout и stderr будут проходить вдоль фильтра.

Цвет терминала, а не файл

Если вы хотите записать цвета в терминал и записать неокрашенный текст в файл, вы можете применить фильтр sed к файлу, записанному tee Например, ваш сценарий будет выглядеть примерно так:

#!/usr/bin/env bash
{
  python somepython.py
  python someotherpython.py
} 2>&1 | tee >(sed -r 's/\x1b\[[0-9;]*m//g' > script.logs)

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

Удалить буферизацию

Предполагая, что вы хотите прочитать содержимое как можно скорее, вы можете отключить буферизацию блоков в python. Это можно сделать с помощью опции -u:

#!/usr/bin/env bash
{
  python -u somepython.py
  python -u someotherpython.py
} 2>&1 | tee >(sed -r 's/\x1b\[[0-9;]*m//g' > script.logs)

Side Примечание: Остерегайтесь CSI

Не все специальные символы основаны на инициаторе последовательности управления ESC [.

Если текст окрашен в зеленый цвет с tput setaf 1, он будет использовать последовательность управления ESC [31m, но если цвет сбрасывается с помощью tput sgr0, последовательность управления может быть ESC (B ESC [m (обратите внимание на последовательность ESC (B). Поэтому, если вы фильтруете только последовательности ESC [, в вашем файле журнала все еще может быть потеря последовательности управления.

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

По этим причинам лучший способ избежать проблем - просто избегать написания управляющих последовательностей из ваших python сценариев. Большинство встроенных программ защищены от этого, проверяя, является ли вывод терминалом, прежде чем выбрать отображение цветов или нет. Когда вывод не является терминалом, он предполагает, что цвета могут вызвать проблемы.

При этом я не знаю, контролируете ли вы сценарии python (или другие вызовы, которые у вас могут быть), но если Вы можете проверить, является ли вывод терминалом. В Bash вы проверяете это следующим образом:

if [ -t 1 ] # does stdout end up on a terminal?
then
  # Display fancy colors
else
  # Minimalist display
fi

В Python это будет:

if sys.stdout.isatty(): # does stdout end up on a terminal?
  # Display fancy colors
else:
  # Minimalist display
...