Фильтрация вывода скрипта во время выполнения

Вопрос или проблема

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

Для упрощения допустим, что каждый из этих циклов for представляет один из моих фоновых скриптов (вывод содержит цветовые коды, кстати):

for i in {0..1000} ; do
    echo -e "\033[0;31mПривет мир\033[0m $i"
    sleep 1
done &

for i in {0..1000} ; do
    echo -e "\033[0;34mПривет мир\033[0m $i"
    sleep 1
done &

Моя первая идея заключалась в том, чтобы перенаправить весь вывод фоновых скриптов в файл, а затем использовать команду read для получения поискового запроса и передачи его в grep вот так:

for i in {0..1000} ; do
    echo -e "\033[0;31mПривет мир\033[0m $i"
    sleep 1
done >> ./output.txt 2>&1 &

for j in {0..1000} ; do
    echo -e "\033[0;34mПривет мир\033[0m $j"
    sleep 1
done >> ./output.txt 2>&1 &

while true ; do
    read -p "Поиск: " query
    clear
    cat ./output.txt | grep "$query"
done

Но с этим есть несколько проблем.

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

Проблема цветового кода: Если я ищу 3, он выведет все строки, потому что цветовые коды содержат 3. Я мог бы, конечно, полностью отфильтровать цвета вот так: cat ./output.txt | sed 's/\x1b\[[0-9;]*m//g' | grep "$query", но я не хочу терять цвет в финальном выводе, так что это не так просто.

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

Есть идеи, как это можно реализовать?

less -R

Вы можете использовать просмотрщик less, чтобы

  • увидеть ANSI цвета с опцией -R
  • искать вперед по шаблону с помощью /шаблон
  • искать назад по шаблону с помощью ?шаблон

  • Навигация с помощью клавиш стрелка и PgUp, PgDn, Home, End.


  • Обратите внимание, что ваш буфер обновляется, когда вы нажимаете End 🙂
  • Проблема цветового кода решена.
  • Ввод не исчезает.

Используйте следующий скрипт для записи,

#!/bin/bash

for i in {0..1000} ; do
    echo -e "\033[0;31mПривет мир\033[0m $i"
    sleep 1
done >> output.txt 2>&1 &

for j in {0..1000} ; do
    echo -e "\033[0;34mПривет мир\033[0m $j"
    sleep 1
done >> output.txt 2>&1 &

Используйте эту командную строку для чтения/проверки,

less -R output.txt

Shellscript с fifo, tail и grep

Альтернативой простой команде less является следующий небольшой shellscript. Предполагается, что вы можете прокручивать достаточно в окне терминала, чтобы видеть и старый вывод. Возможно увеличить буфер, если он недостаточно велик. У меня есть следующие строки в моем `.bashrc`, и я думаю, что они делают то, что вам нужно для этой цели,

HISTFILESIZE=1000000
HISTSIZE=10000

Shellscript для фильтрации и проверки,

#!/bin/bash

# эта функция вызывается, когда отправляется Ctrl-C ##########################

inversvid="\0033[7m"
resetvid="\0033[0m"

function trap_ctrlc ()
{
    # выполнить очистку здесь

    echo " Нажмите <Enter> для продолжения с другим запросом или"
    echo -en "$inversvid"
    read -s -n1 -t5 -p " <x> для выхода " ans
    echo -en "$resetvid"
    if [ "$ans" == "x" ]
    then
     # выйти из shellscript
     # если пропустить, shellscript продолжит выполнение
     echo ""
     exit
    else
     echo ""
    fi
}

##### main #############################################################

# инициализация ловушки для вызова функции trap_ctrlc
# когда сигнал 2 (SIGINT) получен

trap "trap_ctrlc" 2

echo "Прокрутите окно терминала (возможно, увеличьте буфер, чтобы сохранить достаточно строк)

Прервите просмотр отфильтрованного вывода с помощью <ctrl c>"

if [ "$1" == "" ]
then
   read -p "Поиск: " query
else
   query="$@"
fi

# создать fifo

mkfifo fifo

# запуск цикла для запросов и отфильтрованного вывода

while true ; do
 if [ "$query" == "" ]
 then
    read -p "Новый поиск: " query
 fi

# mkfifo fifo
 clear
 tail -n 10000 -f output.txt > fifo &
 grep --color -E "$query" fifo
 sleep 0.1
 query=""
done

Пожалуйста, обратите внимание, что этот shellscript будет видеть также ANSI escape последовательности, поэтому, например, если вы хотите фильтровать по 0, вы увидите все строки (потому что есть ноль в сбросной последовательности). Вы можете использовать расширенные регулярные выражения (опция -E в grep, которые позволяют указать, что вы хотите искать, например \ .?0 или0$.

(Это не является проблемой с less -R).

Ответ или решение

Для решения вашей задачи по фильтрации вывода скриптов во время их выполнения в реальном времени, можно использовать несколько подходов. Рассмотрим наиболее эффективные из них: использование утилиты less с поддержкой ANSI-кодов и создание скрипта на Bash с использованием FIFO, tail и grep.

Использование less -R

Утилита less позволяет просматривать текстовые файлы с поддержкой цветовых кодов ANSI и предоставляет возможности для поиска. Вы можете использовать ее так:

  1. Создайте основной скрипт для генерации вывода:
#!/bin/bash

for i in {0..1000}; do
    echo -e "\033[0;31mHello world\033[0m $i"
    sleep 1
done >> output.txt 2>&1 &

for j in {0..1000}; do
    echo -e "\033[0;34mHello world\033[0m $j"
    sleep 1
done >> output.txt 2>&1 &
  1. Для просмотра выходных данных с возможностью поиска выполните следующую команду в терминале:
less -R output.txt

Используйте / для поиска вперед и ? для поиска назад. Таким образом, вы сможете видеть обновления в реальном времени без потерь цветового оформления.

Скрипт с использованием FIFO, tail и grep

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

#!/bin/bash

inversvid="\033[7m"
resetvid="\033[0m"

function trap_ctrlc {
    echo " Нажмите <Enter> для продолжения с новым запросом или"
    echo -en "$inversvid"
    read -s -n1 -t5 -p " <x> для выхода " ans
    echo -en "$resetvid"
    if [ "$ans" == "x" ]; then
        echo ""
        exit
    else
        echo ""
    fi
}

trap "trap_ctrlc" 2

echo "Прокрутите окно терминала. Для выхода нажмите Ctrl+C."

mkfifo fifo

while true; do
    read -p "Введите строку для поиска: " query
    clear
    tail -n 10000 -f output.txt > fifo &  # Запуск tail в фоне
    grep --color -E "$query" fifo          # Фильтрация результата
    sleep 0.1
done

Примечания

  • Использование less -R является простым решением и позволяет сохранить цветовой вывод, а также предоставляет возможность прокрутки и поиска.
  • Скрипт с использованием FIFO позволяет более интерактивно взаимодействовать с пользователем, однако вводимые команды для поиска будут также иметь свои сложности, например, возможно, придется использовать регулярные выражения для точного поиска.

Рекомендации

  • Убедитесь, что ваш терминал настроен на поддержку ANSI-кодов.
  • Проверьте буфер терминала — возможно, потребуется увеличить его размер для хранения достаточного количества строк вывода.
  • Экспериментируйте с регулярными выражениями в grep для точного поиска по цветному выводу.

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

Оцените материал
Добавить комментарий

Капча загружается...