используя tee для вывода промежуточных результатов на stdout вместо файлов

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

Я знаю, что для того, чтобы захватить содержимое конвейера на промежуточном этапе обработки, мы используем tee как ls /bin /usr/bin | sort | uniq | tee abc.txt | grep out, но что, если я не хочу перенаправлять содержимое после uniq в abc.txt а на экран (через stdout, конечно), так что в итоге у меня на экране будет промежуточное содержимое после uniq, а также содержимое после grep.

Иногда для этого можно использовать /dev/tty…

ls /bin /usr/bin | sort | uniq | tee /dev/tty | grep out | wc

Правка:
(основываясь на комментарии @Jonathan Wheeler) Другой подход — использование замещения процессов bash и tee:
ls....uniq | tee >(pipe1) >(pipe2) | pipe3
что позволяет сохранять раздельные выводы.

... | tee >(pipe1 > out1) >(pipe2 > out2) | pipe3 > out3

ls /bin /usr/bin | sort | uniq | tee /dev/fd/2 | grep out | wc

На системе Linux вы можете использовать ссылки /dev/fd/[num] как именованные каналы в многих случаях. Это продублирует stdout в stderr, который, как правило, является вашим терминалом экраном, но не обязательно.

Как это сделать (пример):

exec 3>&1; ( ls |( tee >&3 ) >/dev/null ); exec 3>&-

Это покажет результат ls и отправит его в небытие.

Чтобы понять ключевую часть, 3>&1, вы можете прочитать Перенаправление ввода/вывода и особенно этот пример.

Короче: >somefile является сокращением для 1>somefile, что, в свою очередь, означает Назначить файловый дескриптор somefile для дескриптора 1 (и отбросить предыдущее значение этого дескриптора, в рамках этого процесса).

Таким образом, 3>&1 означает: Назначить файловый дескриптор 1 (который может быть, но не обязательно должен быть tty) для (до сих пор неиспользуемого) файлового дескриптора 3. Мы фактически используем &3 как временную переменную.

mkfifo myfifo
cat myfifo& ls /bin /usr/bin | sort | uniq | tee myfifo | grep out

mkfifo создает специальный файл FIFO (первый пришел, первый вышел), т.е. именованный канал. 
Запустите асинхронный cat для чтения из fifo, а затем запустите ваш конвейер,
teeя промежуточный результат в fifo.

Это приведет к сообщению [1]+ Done cat myfifo в конце. 
Вы можете подавить это с помощью этого волшебного трюка:

(cat myfifo&); ls /bin /usr/bin | sort | uniq | tee myfifo | grep out

Для долгосрочного, надежного решения вы можете создать постоянный fifo
(например, $HOME/myfifo), а не создавать новый каждый раз. 
Но это будет неудачно, если вы, возможно, запускаете несколько экземпляров этого одновременно. 
В качестве альтернативы,

  • Сгенерируйте уникальное имя (например, с помощью mktemp).
  • Создайте fifo в каталоге, который гарантированно можно записывать (например, /tmp).
  • Удалите fifo в конце команды.

Эта команда сработала для меня.

ls /bin /usr/bin | sort | uniq | tee /dev/pts/0 | grep out

Вы можете проверить, какой у вас терминал, используя команду tty, и заменить tee, чтобы перенаправить вывод на этот терминал.

Ссылки

https://stackoverflow.com/a/18025293/1742825

Если это выполняется из терминала, вы можете

  • начать терминальный мультиплексор, например, tmux или screen
  • разделить ваш терминал – в tmux Ctrl B"
  • в первом окне touch abc.txt, затем tail -f abc.txt
  • перебраться во второе окно и запустить вашу команду. Вы увидите, как файл, созданный tee, обновляется.

http://tldp.org/LDP/abs/html/io-redirection.html

cat stuff | 3>&1 tee 3 | xsel -i

Правка: к сожалению, вышеуказанное ↑ некорректно.
Предыдущий ответ

cat stuff  | tee >(cat) | xsel -i

хороший, хотя бы.

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

Использование команды tee в командной строке Linux для вывода промежуточных результатов потока обработки данных на стандартный вывод (stdout) вместо файлов — это практика, которая может значительно облегчить процесс отладки и мониторинга выполнения команд. Рассмотрим, как это можно сделать с помощью различных методов.

Что такое tee?

Команда tee предназначена для считывания из стандартного ввода и записи в стандартный вывод и один или несколько файлов одновременно. Эта команда удобна, когда необходимо видеть промежуточные результаты обработки данных в терминале и сохранять их в файлах.

Примеры использования tee для вывода на экран

Простой способ с использованием специального устройства

Для отображения данных на экране можно использовать специальное устройство /dev/tty, что представляет собой текущий терминал. Команда:

ls /bin /usr/bin | sort | uniq | tee /dev/tty | grep out

сначала будет выводить список файлов в /bin и /usr/bin, сортировать их, удалять дубликаты и выводить результат на экран, а затем передавать его в команду grep для фильтрации.

Использование описателей файлов

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

exec 3>&1; (ls | (tee >&3) >/dev/null); exec 3>&-

Здесь создается временный дескриптор 3, который будет указывать на стандартный вывод, а после завершения выполнения команды он закрывается. Таким образом, весь вывод будет отображен на экране.

Использование именованных каналов

Создание именованного канала (FIFO) также может быть полезным решением:

mkfifo myfifo
(cat myfifo &) & ls /bin /usr/bin | sort | uniq | tee myfifo | grep out

Именованный канал myfifo позволяет асинхронно считывать данные, которые были прокинуты через tee, при этом, не блокируя основную команду.

Альтернативные методы

  1. Использование объединений процессов (Process Substitution)

    Bash поддерживает процессное подстановку, что позволяет разделить выходные данные на несколько потоков:

    ls /bin /usr/bin | sort | uniq | tee >(cat) | grep out

    Здесь >(cat) помогает визуализировать промежуточный вывод, не сохраняя его в файл.

  2. Перенаправление в конкретный терминал

    Если вы хотите перенаправить вывод на конкретный терминал, можно использовать следующее:

    ls /bin /usr/bin | sort | uniq | tee /dev/pts/N | grep out

    Замените N на номер вашего терминала, который можно определить с помощью команды tty.

  3. Использование терминальных мультиплексоров

    Если у вас есть доступ к инструментам, таким как tmux или screen, вы можете создать несколько окон и в одной из них использовать команду tail -f, чтобы отслеживать файл, в который выводится промежуточный результат:

    touch abc.txt
    tail -f abc.txt

    А в другом окне выполняете:

    ls /bin /usr/bin | sort | uniq | tee abc.txt | grep out

Заключение

Использование tee для непосредственного вывода промежуточных данных на экран при обработке данных в Linux предоставляет гибкие возможности, которые полезны как для разработки, так и для отладки. Методы, описанные выше — это лишь некоторые из способов, которыми можно воспользоваться для достижения этой цели. В зависимости от ваших задач, выбирайте тот подход, который лучше всего соответствует вашим требованиям.

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

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