Вопрос или проблема
Я знаю, что для того, чтобы захватить содержимое конвейера на промежуточном этапе обработки, мы используем 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, чтобы перенаправить вывод на этот терминал.
Ссылки
Если это выполняется из терминала, вы можете
- начать терминальный мультиплексор, например, 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
, при этом, не блокируя основную команду.
Альтернативные методы
-
Использование объединений процессов (Process Substitution)
Bash поддерживает процессное подстановку, что позволяет разделить выходные данные на несколько потоков:
ls /bin /usr/bin | sort | uniq | tee >(cat) | grep out
Здесь
>(cat)
помогает визуализировать промежуточный вывод, не сохраняя его в файл. -
Перенаправление в конкретный терминал
Если вы хотите перенаправить вывод на конкретный терминал, можно использовать следующее:
ls /bin /usr/bin | sort | uniq | tee /dev/pts/N | grep out
Замените
N
на номер вашего терминала, который можно определить с помощью командыtty
. -
Использование терминальных мультиплексоров
Если у вас есть доступ к инструментам, таким как
tmux
илиscreen
, вы можете создать несколько окон и в одной из них использовать командуtail -f
, чтобы отслеживать файл, в который выводится промежуточный результат:touch abc.txt tail -f abc.txt
А в другом окне выполняете:
ls /bin /usr/bin | sort | uniq | tee abc.txt | grep out
Заключение
Использование tee
для непосредственного вывода промежуточных данных на экран при обработке данных в Linux предоставляет гибкие возможности, которые полезны как для разработки, так и для отладки. Методы, описанные выше — это лишь некоторые из способов, которыми можно воспользоваться для достижения этой цели. В зависимости от ваших задач, выбирайте тот подход, который лучше всего соответствует вашим требованиям.