
Это работает идеально:
./foo | ./bar
Но мне бы хотелось что-то вроде этого:
./bar <| ./foo
Таким образом, я могу сделать наоборот и быстрее изменить аргументы foo в командной строке.
Канал должен работать в реальном времени — моя foo
программа никогда не возвращается.
Это возможно ?
решение1
Простым и правильным способом может быть определение функции foobar,
foobar () { ./foo "$@" | ./bar ; }
(либо в командной строке, по мере необходимости, либо в некоторых скриптах запуска, например, ".bashrc"). Затем всякий раз, когда вы делаете:
foobar "this" that "and this also"
это будет сделать
./foo this that "and this also" | ./bar
решение2
./bar < <( ./foo )
Например:cat < <(echo "hello there!")
Чтобы понять, как это работает, рассмотрим части сценария по отдельности.
Этот синтаксис: cat < /path/to/file
прочитает файл /path/to/file
и передаст его как stdin в cat
.
Этот синтаксис: <(echo "hello there!")
означает выполнение команды и присоединение stdout к файловому дескриптору, например /dev/fd/65
. Результатом всего выражения является текст, например /dev/fd/65
, и команда, запущенная параллельно и подающая этот файловый дескриптор.
Теперь, объединив усилия, скрипт запустит правую команду, передаст ее в файловый дескриптор, преобразует этот файловый дескриптор в stdin для левой команды и выполнит левую команду.
Насколько я знаю, никаких накладных расходов нет, это то же самое, что и a | b
, просто синтаксический сахар.
решение3
Я думаю, что можно сделать что-то подобное с помощью именованного канала:
mypipe=$(mktemp -d /tmp/XXXXXX)/pipe
mkfifo $mypipe
grep something < $mypipe & tail > $mypipe -f some_input_file
rm $mypipe
или поместить неизменную часть команды в скрипт оболочки:
./foo "$@" | ./bar
и укажите аргументы foo
в командной строке скрипта:
./myscript <args to foo>