Cara yang baik untuk menemukan perbedaan di antara mereka adalah dengan melakukan sedikit percobaan pada baris perintah. Terlepas dari kesamaan visual dalam penggunaan <
karakter, ia melakukan sesuatu yang sangat berbeda dari pengalihan atau pipa.
Mari kita gunakan date
perintah untuk pengujian.
$ date | cat
Thu Jul 21 12:39:18 EEST 2011
Ini adalah contoh yang tidak berguna tetapi menunjukkan bahwa cat
menerima output dari date
pada STDIN dan meludahkannya kembali. Hasil yang sama dapat dicapai dengan proses substitusi:
$ cat <(date)
Thu Jul 21 12:40:53 EEST 2011
Namun apa yang baru saja terjadi di belakang layar berbeda. Alih-alih diberi aliran STDIN, cat
sebenarnya melewati nama file yang harus dibuka dan dibaca. Anda dapat melihat langkah ini dengan menggunakan echo
alih-alih cat
.
$ echo <(date)
/proc/self/fd/11
Ketika kucing menerima nama file, itu membaca konten file untuk kami. Di sisi lain, gema hanya menunjukkan kepada kita nama file yang dilewati. Perbedaan ini menjadi lebih jelas jika Anda menambahkan lebih banyak pergantian:
$ cat <(date) <(date) <(date)
Thu Jul 21 12:44:45 EEST 2011
Thu Jul 21 12:44:45 EEST 2011
Thu Jul 21 12:44:45 EEST 2011
$ echo <(date) <(date) <(date)
/proc/self/fd/11 /proc/self/fd/12 /proc/self/fd/13
Dimungkinkan untuk menggabungkan proses substitusi (yang menghasilkan file) dan pengalihan input (yang menghubungkan file ke STDIN):
$ cat < <(date)
Thu Jul 21 12:46:22 EEST 2011
Itu terlihat hampir sama tetapi kali ini kucing dilewatkan aliran STDIN bukan nama file. Anda dapat melihat ini dengan mencobanya dengan gema:
$ echo < <(date)
<blank>
Karena gema tidak membaca STDIN dan tidak ada argumen yang disampaikan, kami tidak mendapatkan apa-apa.
Pipa dan pengalihan input mendorong konten ke aliran STDIN. Substitusi proses menjalankan perintah, menyimpan outputnya ke file sementara khusus dan kemudian meneruskan nama file itu sebagai pengganti perintah. Perintah apa pun yang Anda gunakan memperlakukannya sebagai nama file. Perhatikan bahwa file yang dibuat bukan file biasa tetapi pipa bernama yang akan dihapus secara otomatis setelah tidak lagi diperlukan.
[[ -p <(date) ]] && echo true
. Ini menghasilkantrue
ketika saya menjalankannya dengan bash 4.4 atau 3.2.Saya kira Anda berbicara tentang
bash
atau shell canggih lainnya, karena shell posix tidak memiliki proses substitusi .bash
laporan halaman manual:Dengan kata lain, dan dari sudut pandang praktis, Anda dapat menggunakan ekspresi seperti berikut ini
sebagai nama file untuk perintah lain yang membutuhkan file sebagai parameter. Atau Anda dapat menggunakan pengalihan untuk file seperti itu:
Kembali ke pertanyaan Anda, menurut saya proses substitusi dan pipa tidak memiliki banyak kesamaan.
Jika Anda ingin memasang secara berurutan output dari beberapa perintah, Anda dapat menggunakan salah satu dari formulir berikut:
tetapi Anda juga dapat menggunakan pengalihan pada substitusi proses
akhirnya, jika
command3
menerima parameter file (sebagai pengganti stdin)sumber
Berikut adalah tiga hal yang dapat Anda lakukan dengan proses penggantian yang tidak mungkin dilakukan sebaliknya.
Beberapa input proses
Tidak ada cara untuk melakukan ini dengan pipa.
Mempertahankan STDIN
Katakanlah Anda memiliki yang berikut ini:
Dan Anda ingin menjalankannya secara langsung. Berikut ini gagal total. Bash sudah menggunakan STDIN untuk membaca skrip, jadi input lain tidak mungkin.
Tetapi cara ini bekerja dengan sempurna.
Substitusi proses keluar
Perhatikan juga bahwa proses substitusi juga berfungsi sebaliknya. Jadi Anda dapat melakukan sesuatu seperti ini:
Itu sedikit contoh yang berbelit-belit, tetapi mengirimkan stdout ke
/dev/null
, sementara memipatkan stderr ke skrip sed untuk mengekstrak nama file yang menampilkan galat "Izin ditolak" ditampilkan, dan kemudian mengirim MEREKA hasil ke file.Perhatikan bahwa perintah pertama dan pengalihan stdout ada dalam tanda kurung ( subkulit ) sehingga hanya hasil dari perintah ITU yang dikirim
/dev/null
dan tidak mengacaukan dengan sisa baris.sumber
diff
contoh Anda mungkin ingin peduli tentang kasus di manacd
mungkin gagal:diff <(cd /foo/bar/ && ls) <(cd /foo/baz && ls)
.Jika perintah mengambil daftar file sebagai argumen dan memproses file-file tersebut sebagai input (atau output, tetapi tidak umum), masing-masing file tersebut dapat berupa pipa bernama atau / dev / fd file semu yang disediakan secara transparan oleh proses subsitusi:
Ini akan "mem-pipe" output dari tiga perintah untuk disortir, karena sort dapat mengambil daftar file input pada baris perintah.
sumber
<()
, seperti banyak fitur shell canggih, pada awalnya merupakan fitur ksh dan diadopsi oleh bash dan zsh.psub
secara khusus fitur ikan, tidak ada hubungannya dengan POSIX.Perlu dicatat bahwa proses substitusi tidak terbatas pada formulir
<(command)
, yang menggunakan outputcommand
sebagai file. Itu bisa dalam bentuk>(command)
yang mengumpankan file sebagai inputcommand
juga. Ini juga disebutkan dalam kutipan manual bash dalam jawaban @ enzotib.Untuk
date | cat
contoh di atas, perintah yang menggunakan proses substitusi formulir>(command)
untuk mencapai efek yang sama adalah,Perhatikan bahwa
>
sebelumnya>(cat)
diperlukan. Sekali lagi ini dapat digambarkan dengan jelasecho
seperti pada jawaban @ Caleb.Jadi, tanpa tambahan
>
,date >(cat)
akan sama dengandate /dev/fd/63
yang akan mencetak pesan ke stderr.Misalkan Anda memiliki program yang hanya menggunakan nama file sebagai parameter dan tidak memproses
stdin
ataustdout
. Saya akan menggunakan skrip yang terlalu disederhanakanpsub.sh
untuk menggambarkan hal ini. Isipsub.sh
isPada dasarnya, ini menguji bahwa kedua argumennya adalah file (tidak harus file biasa) dan jika ini masalahnya, tulislah bidang pertama dari setiap baris
"$1"
untuk"$2"
menggunakan awk. Kemudian, perintah yang menggabungkan semua yang disebutkan sejauh ini adalah,Ini akan dicetak
dan setara dengan
tetapi yang berikut tidak akan berfungsi, dan kami harus menggunakan proses substitusi di sini,
atau bentuknya yang setara
Jika
./psub.sh
juga membacastdin
selain apa yang disebutkan di atas, maka bentuk setara seperti itu tidak ada, dan dalam hal itu tidak ada yang bisa kita gunakan sebagai pengganti proses substitusi (tentu saja Anda juga dapat menggunakan pipa atau file temp bernama, tapi itu lain cerita).sumber