Если Вы находитесь на современном Linux, Вы могли бы использовать inotifywait
, одна из программ командной строки от пакета inotify-инструментов. Я не сделал этого, но это похоже inotifywait
мог использоваться в сценарии оболочки для сброса символьной ссылки и остановки и перезапуска tail -f
на символьной ссылке. Вы могли бы даже смочь избавиться от символьной ссылки и просто выследить текущий файл журнала.
Не используя inotify, возможно записать Вашу собственную подобную хвосту программу, которая проверяет, чтобы видеть, изменилось ли inode количество имени файла, из которого это читает. В той точке может закрыться подобная хвосту программа, это - старый дескриптор файла, и получите новый дескриптор файла для теперь различного имени файла. Это - хитрая программа для записи, и это подвержено условиям состязания.
Можно использовать tee
и замена процесса на это:
cat file.txt | tee >(pbcopy) | grep errors
Это отправит весь вывод cat file.txt
кому: pbcopy
, и Вы только получите результат grep
на Вашей консоли.
Можно вставить несколько процессов tee
часть:
cat file.txt | tee >(pbcopy) >(do_stuff) >(do_more_stuff) | grep errors
Просто игра с заменой процесса.
mycommand_exec |tee >(grep ook > ook.txt) >(grep eek > eek.txt)
grep
два двоичных файла, которые имеют тот же вывод от mycommand_exec
как их процесс определенный вход.
Получите команду STDOUT
к переменной и повторному использованию это так много раз, как Вам нравится:
commandoutput="$(command-to-run)"
echo "$commandoutput" | grep -i errors
echo "$commandoutput" | pbcopy
Если необходимо получить STDERR
также, затем используйте 2>&1
в конце команды, как так:
commandoutput="$(command-to-run 2>&1)"
Можно указать несколько имен файлов к tee
, и кроме того стандартный вывод может быть передан по каналу в одну команду. Для диспетчеризации вывода нескольким командам необходимо создать несколько каналов и указать каждого из них как один вывод tee
. Существует несколько способов сделать это.
Если Ваша оболочка является ksh93, ударом или zsh, можно использовать замену процесса. Это - способ передать канал команде, которая ожидает имя файла. Оболочка создает канал и передает имя файла как /dev/fd/3
к команде. Число является дескриптором файла, с которым подключен канал. Некоторые варианты Unix не поддерживают /dev/fd
; на них именованный канал используется вместо этого (см. ниже).
tee >(command1) >(command2) | command3
В любой оболочке POSIX можно использовать несколько дескрипторов файлов явно. Это требует варианта Unix, который поддерживает /dev/fd
, начиная со всех кроме одного из выводов tee
должен быть указан по имени.
{ { { tee /dev/fd/3 /dev/fd/4 | command1 >&9;
} 3>&1 | command2 >&9;
} 4>&1 | command3 >&9;
} 9>&1
Самый основной и портативный метод должен использовать именованные каналы. Оборотная сторона - то, что необходимо найти перезаписываемый каталог, создать каналы и вымыться впоследствии.
tmp_dir=$(mktemp -d)
mkfifo "$tmp_dir/f1" "$tmp_dir/f2"
command1 <"$tmp_dir/f1" & pid1=$!
command2 <"$tmp_dir/f2" & pid2=$!
tee "$tmp_dir/f1" "$tmp_dir/f2" | command3
rm -rf "$tmp_dir"
wait $pid1 $pid2
tee "$tmp_dir/f1" "$tmp_dir/f2" | command3
должен, конечно, быть command3 | tee "$tmp_dir/f1" "$tmp_dir/f2"
, поскольку Вы хотите stdout command3
переданный по каналу к tee
, нет? Я протестировал Вашу версию под dash
и tee
блоки, неограниченно долго ожидая входа, но переключая порядок привели к ожидаемому результату.
– Adrian Günter
10.04.2018, 22:21
command
, command2
и command3
.
– Gilles 'SO- stop being evil'
11.04.2018, 01:04
Если Вы используете zsh
, то Вы можете воспользоваться возможностями функции MULTIOS
, т.е. полностью избавиться от команды tee
:
uname >file1 >file2
просто запишет выход uname
в два разных файла: file1
и file2
, что эквивалентно имени uname | tee file1 >file2
Аналогично перенаправление стандартных входов
wc -l <file1 <file2
эквивалентно cat file1 file2 | wc -l
(пожалуйста, обратите внимание, что это не то же самое, что wc -l file1 file2
, затем подсчитывает количество строк в каждом файле в отдельности).
Конечно, вы также можете использовать MULTIOS
для перенаправления вывода не в файлы, а в другие процессы, используя подстановку процессов, например:
echo abc > >(grep -o a) > >(tr b x) > >(sed 's/c/y/')
Это может быть полезно: http://www.spinellis.gr/sw/dgsh/ (оболочка ориентированного графа) Похоже на замену bash, поддерживающую более простой синтаксис для " команды multipipe.
Для достаточно небольшого вывода, производимого командой, мы можем перенаправить вывод во временный файл и отправить этот временный файл командам в цикле. Это может быть полезно, когда порядок выполнения команд может иметь значение.
Например, это может сделать следующий сценарий:
#!/bin/sh
temp=$( mktemp )
cat /dev/stdin > "$temp"
for arg
do
eval "$arg" < "$temp"
done
rm "$temp"
Тестовый запуск в Ubuntu 16.04 с / bin / sh
в качестве тире
оболочки:
$ cat /etc/passwd | ./multiple_pipes.sh 'wc -l' 'grep "root"'
48
root:x:0:0:root:/root:/bin/bash
Вот быстрое -и -грязное частичное решение, совместимое с любой оболочкой, включая busybox
.
Более узкая проблема, которую он решает, состоит в том, что :вывод полного stdout
на одну консоль и фильтрация на другой, без временных файлов или именованных каналов.
tty
. Предположим /dev/pty/2
. the_program | tee /dev/pty/2 | grep ImportantLog:
Вы получаете один полный журнал и один отфильтрованный.
Другой вариант:
$ cat file.txt | tee >(head -1 1>&2) | grep foo
Работает путем перенаправления аргумента файла tee
в подстановку процесса bash , где этот процесс — head
, который печатает только одну строку (заголовка )и перенаправляет свой собственный вывод вstderr
(чтобы было видно ).
pbcopy
, но стоящий упоминания в целом: безотносительно выводов замены процесса также замечен следующим сегментом канала, после исходного входа; например:seq 3 | tee >(cat -n) | cat -e
(cat -n
нумерует входные строки,cat -e
новые строки меток с$
; Вы будете видеть этоcat -e
применяется и к исходному входу (сначала) и (затем) к выводу отcat -n
). Вывод от нескольких замен процесса прибудет в недетерминированный порядок. – mklement0 09.12.2014, 06:47>(
только работы вbash
. Если Вы пробуете то использование, например,sh
ничего не выйдет. Важно сделать это уведомление. – AAlvz 16.12.2014, 18:31dash
, которые действуют какsh
на Ubuntu, не поддерживает его, и даже сам Bash деактивирует функцию при вызове какsh
или когдаset -o posix
в действительности. Однако это не просто Bash, который поддерживает замены процесса:ksh
иzsh
поддерживайте их также (не уверенный в других). – mklement0 15.04.2015, 05:59bash
иksh
-zsh
по-видимому, не отправляет вывод с выходных замен процесса на конвейер (возможно, это предпочтительно, потому что он не загрязняет то, что отправляется в следующий конвейерный сегмент - хотя он все еще печатает). Во всех упомянутых оболочках, однако, это обычно - не хорошая идея иметь единственный конвейер, в котором регулярный вывод stdout и вывод от замен процесса смешаны - выходное упорядочивание не будет предсказуемо способом, который может только нечасто появляться или с наборами данных крупносерийного производства. – mklement0 22.10.2016, 08:39