Berikan pipa ke perintah yang mengharapkan nama file

19

Katakanlah saya memiliki perintah fooyang membutuhkan argumen nama file: foo myfile.txt. Mengganggu, footidak membaca dari input standar. Alih-alih file yang sebenarnya, saya ingin meneruskannya hasil dari perintah lain (pada kenyataannya pv,, yang akan menampilkan file dan menampilkan meteran kemajuan sebagai efek samping).

Apakah ada cara untuk mewujudkannya? Sepertinya tidak ada trik yang bisa saya lakukan.

( foodalam hal ini adalah skrip PHP yang saya percaya memproses file secara berurutan).

Saya menggunakan Ubuntu dan Bash

EDIT Maaf untuk uraian masalah yang sedikit tidak jelas, tapi inilah jawabannya yang melakukan apa yang saya inginkan:

pv longfile.txt | foo /dev/stdin

Sangat jelas sekarang saya melihatnya.

Steve Bennett
sumber
Apakah Anda mencari satu garis?
Dave Forgac
Apakah Anda yakin foo tidak menerima argumen "-" untuk membuatnya dibaca dari stdin?
rackandboneman
Sayangnya ya, dalam hal ini - ini adalah skrip php.
Steve Bennett
Ya, sebenarnya. .
Steve Bennett

Jawaban:

19

Jika saya mengerti apa yang ingin Anda lakukan dengan benar, Anda dapat melakukannya dengan fitur substitusi perintah bash:

foo <(somecommand | pv)

Ini melakukan sesuatu yang mirip dengan apa yang mkfifodisarankan oleh jawaban, kecuali bahwa bash menangani detail untuk Anda (dan akhirnya mengirimkan sesuatu seperti / dev / fd / 63 ke perintah, daripada pipa bernama biasa). Anda juga dapat melakukannya secara lebih langsung seperti ini:

somecommand | pv | foo /dev/stdin
Gordon Davisson
sumber
1
oh bagus Ini pv inputfile.txt | foo /dev/stdinpersis apa yang saya cari, tetapi tidak terpikirkan.
Steve Bennett
Woot! / dev / stdin
sage
<(.)bekerja untukku. Apakah sintaks ini didokumentasikan dalam manual Bash? Saya mengerti (.)sebagai substitusi perintah didokumentasikan, tetapi tidak melihat kombinasi dengan <dijelaskan.
flow2k
@ flow2k Ini disebut "proses substitusi" - lihat bagian 3.5.6 dari manual bash .
Gordon Davisson
Mengerti. Anda benar - ini menyebutkan bahwa ia menggunakan pipa bernama / mkfifo.
flow2k
2
ARRAY=(`pv whatever`); for FILE in $ARRAY; do foo $FILE; done
Hyppy
sumber
2

Pertanyaan Unix SE ini memiliki jawaban yang menunjukkan cara membuat pipa bernama sementara:

Shell Script mktemp, apa metode terbaik untuk membuat pipa bernama sementara?

Berdasarkan jawaban di sana, Anda dapat melakukan sesuatu seperti berikut:

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

Anda kemudian dapat menonton pipa dengan:

foo $tmppipe

Kemudian hapus ketika Anda selesai dengan itu.

Dave Forgac
sumber
1

Coba gunakan mkfifo.

mkfifo file_read_by_foo; pv ... > file_read_by_foo 

Di shell lain, jalankan foo file_read_by_foo

menjadi paling lucu
sumber
0

xargs tampaknya bekerja dengan baik untuk ini:

echo longfile.txt | xargs pv
MadHatter mendukung Monica
sumber
Itu melakukan sesuatu yang berbeda: menjalankan pvbeberapa kali, masing-masing dengan satu atau lebih garis yang diambil longfile.txt. Sama sekali tidak seperti yang saya kejar di sini.
Steve Bennett