Beberapa input standar? Bagaimana?

36

Dari pos commandlinefu ini :

$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)

Sepertinya beberapa input standar tetapi --- jika saya ingat kursus Linux Porgramming saya dengan benar --- ini tidak mungkin. Saya pikir, menurut definisi, input standar adalah satu aliran.

Mungkin ini ada hubungannya dengan stdin? Dapatkah seseorang menjelaskan hal ini kepada saya; mungkin memberikan tautan ke dokumentasi.

Bonus: Bagaimana skrip menangani banyak aliran ini? Jika seseorang dapat memberikan contoh Python atau Perl, itu akan sangat membantu.

Belmin Fernandez
sumber
1
Pertanyaan bagus. Jika Anda tidak tahu, ada situs tanya jawab unix / linux: unix.stackexchange.com
Matt Ellen
2
Dokumentasi untuk penggantian proses: gnu.org/software/bash/manual/bashref.html#Process-Substitution
glenn jackman
Catatan: di Bash itu <(…); dalam sintaks substitusi proses Zsh adalah =(…).
Kamil Maciorowski

Jawaban:

27

Ini bukan beberapa input standar. Ini adalah bash'ism yang disebut 'Substitusi Proses' http://tldp.org/LDP/abs/html/process-sub.html

Ini membuat file pseudo ( /dev/fd/something) untuk setiap substitusi. Ini sangat berguna. Perintah hanya bisa dibaca sebagai stream, artinya tidak bisa bolak-balik dengan fseek. Perlu membacanya sebagai aliran byte, seperti pipa.

BONUS Jawab

Anda tidak perlu melakukan terlalu banyak untuk menggunakan ini. Sejauh menyangkut skrip Anda, skrip ini mendapatkan nama file yang valid pada baris perintah, yang dapat dibuka () seperti yang lainnya. Seperti yang orang lain katakan, Anda akan lihat diff /dev/fd/XX /dev/fd/YY. Jika Anda melakukan stat () pada salah satu file pseudo ini, Anda akan melihat itu adalah nama pipa, dan Anda harus memperlakukannya dengan semantik pipa - yaitu tanpa fseek () atau ftell (). Jika Anda melakukan tes stat () untuk secara eksplisit melihat apakah itu file (misalnya [ -f $1 ]) ini akan pecah - ini diimplementasikan sebagai pipa bernama setelah semua.

Homolka yang kaya
sumber
Referensi lain yang bagus untuk substitusi proses bash - wiki.bash-hackers.org/syntax/expansion/proc_subst
studgeek
Dan apa yang disarankan penggunaan fitur ini? Mendukungnya kapan pun program Anda dapat bekerja secara wajar dengan aliran alih-alih memerlukan file dengan akses acak?
masterxilo
7

<(...)melakukan proses substitusi dalam bash. Output dari proses dalam parens dikirim ke file deskriptor tambahan di luar 3 normal, dan nama file dikembalikan sesuai dengan deskriptor file itu. Dengan cara ini, output dari suatu perintah dapat diperlakukan sebagai nama file untuk diteruskan ke perintah lain.

Ignacio Vazquez-Abrams
sumber
7

Ada satu stdindan satu stdout untuk setiap proses . Mereka biasanya terhubung ke terminal, tetapi mereka dapat dialihkan secara terpisah dari satu sama lain.

Dalam contoh tersebut, ada dua wgetproses yang terlibat, masing-masing mendapatkan sendiri stdindan stdout. Setiap wgetproses menulis -, yang merupakan prosesnya stdout. Kemudian bashsubstitusi proses <(...)menghubungkan stdoutproses ke file pseudo yang unik, yang diffdapat dibaca. Perhatikan bahwa dua proses penggantian menghasilkan dua file pseudo yang berbeda! Jadi, difflihat sesuatu seperti:

diff /dev/fd/XX /dev/fd/YY

dimana stdoutdari wget -q -O - URL1terhubung ke /dev/fd/XX, dan stdoutdari wget -q -O - URL2ke /dev/fd/YY.

musiphil
sumber