Dalam bash
, saya dapat menggunakan Proses Pergantian dan memperlakukan output dari suatu proses seolah-olah itu adalah file yang disimpan di disk:
$ echo <(ls)
/dev/fd/63
$ ls -lAhF <(ls)
lr-x------ 1 root root 64 Sep 17 12:55 /dev/fd/63 -> pipe:[1652825]
sayangnya, Proses Pergantian tidak didukung di dash
.
Apa cara terbaik untuk meniru Process Substitution
di dash?
Saya tidak ingin menyimpan output sebagai file sementara di suatu tempat ( /tmp/
) dan kemudian harus menghapusnya. Apakah ada cara alternatif?
process-substitution
dash
Martin Vegter
sumber
sumber
bash
pada perangkat Anda?/dev/fd
dan penggunaanxz -cd <file>
alih-alihcat <file> | xz -d
) bisa jadixz -cd "$1" | { xz -cd "$2" | { diff /dev/fd/3 /dev/fd/4; } 3<&0; } 4<&0
.Jawaban:
Pertanyaan dalam pemberitahuan karunia saat ini:
sepertinya punya jawaban di sini .
Seperti yang ditunjukkan dalam jawaban Gilles , ide umumnya adalah untuk mengirim output dari perintah "produser" ke file perangkat baru 1 pada berbagai tahapan pipa, menjadikannya tersedia untuk perintah "konsumen", yang mungkin dapat menggunakan nama file sebagai argumen ( dengan asumsi bahwa sistem Anda memberi Anda akses ke deskriptor file sebagai
/dev/fd/X
).Cara paling sederhana untuk mencapai apa yang Anda cari mungkin adalah:
(Menggunakan
file1.xz
di tempat"$1"
untuk keterbacaan danxz -cd
bukancat ... | xz -d
karena satu perintah sudah cukup).Output dari perintah "produser" pertama
xz -cd file1.xz
,, disalurkan ke perintah gabungan ({...}
); tetapi, alih-alih dikonsumsi langsung sebagai input standar dari perintah berikutnya, itu digandakan ke file deskriptor3
dan dengan demikian dapat diakses oleh semua yang ada di dalam perintah gabungan sebagai/dev/fd/3
. Output dari perintah "produser" keduaxz -cd file2.xz
, yang tidak mengkonsumsi input standar atau apapun dari deskriptor file3
, kemudian disalurkan ke perintah "konsumen"diff
, yang membaca dari input standar dan dari/dev/fd/3
.Duplikasi pemipaan dan deskriptor file dapat ditambahkan untuk menyediakan file perangkat sebanyak mungkin perintah "produsen", misalnya:
Meskipun mungkin tidak relevan dalam konteks pertanyaan spesifik Anda, perlu dicatat bahwa:
cmd1 <(cmd2) <(cmd3)
,cmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
dan( cmd2 | ( cmd3 | ( cmd1 /dev/fd/3 /dev/fd/4 ) 4<&0 ) 3<&0 )
memiliki efek potensial yang berbeda pada lingkungan eksekusi awal.Bertentangan dengan apa yang terjadi di
cmd1 <(cmd2) <(cmd3)
,cmd3
dancmd1
dicmd2 | { cmd3 | { cmd1 /dev/fd/3 /dev/fd/4; } 4<&0; } 3<&0
tidak akan dapat membaca input apa pun dari pengguna. Itu akan membutuhkan penjelas file lebih lanjut. Misalnya, untuk mencocokkanAnda akan membutuhkan sesuatu seperti
1 Lebih banyak tentang mereka dapat ditemukan di U&L, misalnya dalam Memahami / dev dan subdir serta file-nya .
sumber
Anda dapat mereproduksi apa yang shell lakukan di bawah tenda dengan melakukan pipa ledeng secara manual. Jika sistem Anda memiliki entri, Anda dapat menggunakan pengacakan file descriptor: Anda dapat menerjemahkan
/dev/fd/NNN
untuk
Saya telah menunjukkan contoh yang lebih kompleks untuk menggambarkan banyak input dan output. Jika Anda tidak perlu membaca dari input standar, dan satu-satunya alasan Anda menggunakan substitusi proses adalah bahwa perintah tersebut membutuhkan nama file yang eksplisit, Anda cukup menggunakan
/dev/stdin
:Tanpa , Anda perlu menggunakan pipa bernama . Pipa bernama adalah entri direktori, jadi Anda perlu membuat file sementara di suatu tempat, tetapi file itu hanya nama, itu tidak mengandung data apa pun.
/dev/fd/NNN
sumber
</dev/fd/8 >/dev/fd/9
tidak setara dengan<&8 >&9
di Linux dan harus dihindari di sana.diff <(cat "$2" | xz -d) <(cat "$1" | xz -d)
?Saya pikir pipa bernama lebih mudah untuk grok daripada pengalihan, jadi secara sederhana:
p1
danp2
sementara pipa bernama, mereka bisa dinamai apa saja.Akan lebih pintar untuk membuat pipanya
/tmp
, misalnya dalam direktori yang ditunjukkan oleh jawaban Gilles , dan perhatikan bahwa Anda tidak perlu dicat
sini, jadi:(Anda mungkin bisa pergi tanpa tanda kutip juga, karena
mktemp
kemungkinan akan membuat nama file "bagus".)Solusi pipa memang memiliki peringatan bahwa jika perintah utama (
diff
) mati sebelum membaca semua input, proses latar belakang dapat dibiarkan menggantung.sumber
Bagaimana dengan:
sumber