Есть некоторые команды, которые фильтруют или воздействуют на ввод, а затем передают его как вывод, как я обычно думаю, stdout
- но некоторые команды просто берут stdin
и делают то, что с ним делают, и ничего не выводят.
Я знаком с OS X и так есть два , которые приходят на ум сразу же являются pbcopy
и pbpaste
- которые являются средством доступа к системному буферу.
Во всяком случае, я знаю, что если я хочу взять стандартный вывод и выплюнуть вывод, чтобы перейти к обоим stdout
и файл, то я могу использовать tee
команду. И я немного знаю xargs
, но не думаю, что это то, что я ищу.
Я хочу знать, как я могу разделить, stdout
чтобы перейти между двумя (или более) командами. Например:
cat file.txt | stdout-split -c1 pbcopy -c2 grep -i errors
Вероятно, есть лучший пример, чем тот, но мне действительно интересно знать, как я могу отправить стандартный вывод команде, которая не передает его, и, в то же время, stdout
не отключаясь - я не спрашиваю о том, как cat
файл и grep
часть его и скопировать в буфер обмена - конкретные команды не так важны.
Кроме того - я не спрашиваю, как отправить это в файл и stdout
- это может быть «дублирующий» вопрос (извините), но я немного искал и смог найти только похожие вопросы, которые спрашивали о том, как разделить между stdout и файлом - и ответы на эти вопросы, казалось, были tee
, что я не думаю, что будет работать для меня.
Наконец, вы можете спросить: «Почему бы просто не сделать pbcopy последней вещью в цепочке труб?» и мой ответ: 1) что, если я хочу использовать его и все еще видеть вывод в консоли? 2) что если я хочу использовать две команды, которые не выводятся stdout
после обработки ввода?
Да, и еще одна вещь - я понимаю, что мог бы использовать tee
именованную трубу ( mkfifo
), но я надеялся, что это можно будет сделать inline, сжато, без предварительной настройки :)
Ответы:
Вы можете использовать
tee
и обрабатывать замену для этого:Это отправит весь вывод
cat file.txt
вpbcopy
, и вы получите только результатgrep
на своей консоли.Вы можете поместить несколько процессов в
tee
детали:источник
pbcopy
, но стоит отметить , в целом: какие бы замены процесса выходов также рассматривается следующий сегмент трубы, после первоначального ввода; Например:seq 3 | tee >(cat -n) | cat -e
(cat -n
нумерует входные строки,cat -e
отмечает новые строки$
; вы увидите, чтоcat -e
это применяется как к исходному вводу (сначала), так и (затем) к выходу изcat -n
). Вывод из нескольких замен процесса будет поступать в недетерминированном порядке.>(
Работает только вbash
. Если вы попробуете это с использованием, например,sh
он не будет работать. Важно сделать это уведомление.dash
, который действует какsh
в Ubuntu, не поддерживает его, и даже сам Bash деактивирует функцию, когда вызывается какsh
или когдаset -o posix
действует. Однако не только Bash поддерживает подстановки процессов, ноksh
иzsh
поддерживает их (не уверен в других).bash
иksh
- по-zsh
видимому , не посылает выходной сигнал из выходного процесса замен через трубопровод (возможно, что это предпочтительнее , потому что он не загрязняет окружающую среды , что отправляется к следующему сегменту трубопровода - хотя это все еще печатает ). Однако во всех упомянутых оболочках, как правило, не очень хорошая идея иметь один конвейер, в котором обычные выходные данные stdout и выходные данные подстановок процессов смешаны - упорядочение вывода не будет предсказуемым, что может происходить только нечасто или с большими наборы выходных данных.Вы можете указать несколько имен файлов
tee
, и, кроме того, стандартный вывод может быть передан в одну команду. Чтобы распределить вывод по нескольким командам, вам нужно создать несколько каналов и указать каждый из них как один выводtee
. Есть несколько способов сделать это.Процесс замещения
Если ваша оболочка ksh93, bash или zsh, вы можете использовать процесс подстановки. Это способ передать канал команде, которая ожидает имя файла. Оболочка создает канал и передает имя файла подобно
/dev/fd/3
команде. Число - это дескриптор файла , к которому подключен канал. Некоторые варианты Unix не поддерживают/dev/fd
; на них вместо этого используется именованный канал (см. ниже).Файловые дескрипторы
В любой оболочке POSIX вы можете явно использовать несколько файловых дескрипторов . Для этого требуется вариант Unix, который поддерживает
/dev/fd
, так как все выходные данные, кроме одного,tee
должны быть указаны по имени.Именованные трубы
Самый основной и портативный метод - это использование именованных каналов . Недостатком является то, что вам нужно найти доступный для записи каталог, создать каналы и выполнить очистку после этого.
источник
tee "$tmp_dir/f1" "$tmp_dir/f2" | command3
безусловно , должно бытьcommand3 | tee "$tmp_dir/f1" "$tmp_dir/f2"
, как вы хотите стандартный вывод поcommand3
конвейеруtee
, нет? Я проверил вашу версиюdash
иtee
блокировал бесконечно, ожидая ввода, но переключение порядка дало ожидаемый результат.command
,command2
иcommand3
.<command> | bash -c 'tee >(command1) >(command2) | command3'
. Это помогло в моем случае.Просто поиграйся с процессом подстановки.
grep
два двоичныхmycommand_exec
файла, которые имеют тот же вывод, что и их входные данные, специфичные для процесса.источник
Если вы используете,
zsh
то можете воспользоваться преимуществамиMULTIOS
функции, то есть полностью избавиться отtee
команды:просто запишет вывод
uname
двух разных файлов:file1
иfile2
, что эквивалентноuname | tee file1 >file2
Аналогично перенаправление стандартных входов
эквивалентно
cat file1 file2 | wc -l
(обратите внимание, что это не то же самоеwc -l file1 file2
, что позже подсчитывает количество строк в каждом файле отдельно).Конечно, вы также можете использовать
MULTIOS
перенаправление вывода не в файлы, а в другие процессы, используя подстановку процессов, например:источник
MULTIOS
это опция, которая включена по умолчанию (и может быть отключена с помощьюunsetopt MULTIOS
).Для относительно небольшого вывода, создаваемого командой, мы можем перенаправить вывод во временный файл и отправить этот временный файл командам в цикле. Это может быть полезно, когда порядок выполняемых команд может иметь значение.
Следующий скрипт, например, может сделать это:
Тест работает на Ubuntu 16.04 с ,
/bin/sh
какdash
оболочки:источник
Захватите команду
STDOUT
в переменную и используйте ее столько раз, сколько захотите:Если вам
STDERR
тоже нужно захватить , то используйте2>&1
в конце команды, например так:источник
Это может быть полезно: http://www.spinellis.gr/sw/dgsh/ (оболочка ориентированного графа). Похоже на замену bash, поддерживающую более простой синтаксис для команд "multipipe".
источник
Вот быстрое частичное решение, совместимое с любой оболочкой, включая
busybox
.Более узкая проблема, которую он решает: вывести полную
stdout
на одну консоль и отфильтровать ее на другой, без временных файлов или именованных каналов.tty
. Давайте предположим/dev/pty/2
.the_program | tee /dev/pty/2 | grep ImportantLog:
Вы получаете один полный журнал и один отфильтрованный.
источник