Передать канал команде, которая ожидает имя файла

19

Скажем , у меня есть команда , fooкоторая принимает имя файла аргумент: foo myfile.txt. Досадно, fooне читает со стандартного ввода. Вместо реального файла я хотел бы передать ему результат другой команды (в действительности pv, которая будет отслеживать файл и выводить индикатор выполнения в качестве побочного эффекта).

Есть ли способ сделать это? Ничто в моей сумке трюков, кажется, не делает этого.

( fooв данном случае это PHP-скрипт, который, я считаю, обрабатывает файл последовательно).

Я использую Ubuntu и Bash

РЕДАКТИРОВАТЬ Извините за немного неясное описание проблемы, но вот ответ, который делает то, что я хочу:

pv longfile.txt | foo /dev/stdin

Очень очевидно теперь, когда я это вижу.

Стив Беннетт
источник
Вы ищете однострочник?
Дэйв Форгач
Вы уверены, что foo не принимает аргумент "-" для чтения из стандартного ввода?
rackandboneman
К сожалению, да, в данном случае - это скрипт php.
Стив Беннетт
Да собственно ,
Стив Беннетт

Ответы:

19

Если я понимаю, что вы хотите сделать правильно, вы можете сделать это с помощью функции подстановки команд в bash:

foo <(somecommand | pv)

Это делает что-то похожее на то, что mkfifoпредлагают ответы на основе, за исключением того, что bash обрабатывает детали для вас (и в итоге он передает в команду что-то вроде / dev / fd / 63, а не обычный именованный канал). Вы также можете сделать это еще более прямо, как это:

somecommand | pv | foo /dev/stdin
Гордон Дэвиссон
источник
1
о, хороший! Это pv inputfile.txt | foo /dev/stdinименно то, что я искал, но не думал.
Стив Беннетт
Woot! / dev / stdin
мудрец
<(.)работал на меня. Задокументирован ли этот синтаксис в руководстве по Bash? Я понимаю, (.)как подстановка команды задокументирована, но не видела ее комбинации с <объясненной.
flow2k
@ flow2k Это называется «замена процесса» - см. раздел 3.5.6 руководства по bash .
Гордон Дэвиссон
Понял. Вы правы - в нем упоминается, что он использует именованные каналы / mkfifo.
flow2k
2
ARRAY=(`pv whatever`); for FILE in $ARRAY; do foo $FILE; done
Hyppy
источник
2

На этот вопрос Unix SE есть ответ, который показывает, как создать временный именованный канал:

Shell Script mktemp, каков наилучший способ создания временного именованного канала?

Основываясь на ответах, вы можете сделать что-то вроде следующего:

tmppipe=$(mktemp -u)
mkfifo -m 600 "$tmppipe"
pv examplefile > $tmppipe

Затем вы можете посмотреть трубу с:

foo $tmppipe

Затем удалите его, когда закончите.

Дейв Форгак
источник
1

Попробуйте использовать mkfifo.

mkfifo file_read_by_foo; pv ... > file_read_by_foo 

В другой оболочке запустите foo file_read_by_foo

becomingwisest
источник
0

xargs кажется, хорошо работает для этого:

echo longfile.txt | xargs pv
MadHatter поддерживает Монику
источник
Это делает что-то другое: работает pvнесколько раз, каждый с одной или несколькими линиями longfile.txt. Не совсем то, что я здесь после.
Стив Беннетт