Pipa adalah file yang dibuka dalam sistem file-dalam-kernel dan tidak dapat diakses sebagai file pada-disk biasa. Secara otomatis buffered hanya untuk ukuran tertentu dan pada akhirnya akan memblokir ketika penuh. Tidak seperti file yang bersumber pada perangkat blok, pipa berperilaku sangat seperti perangkat karakter, dan umumnya tidak mendukung lseek()
dan data yang dibaca dari mereka tidak dapat dibaca lagi seperti yang mungkin Anda lakukan dengan file biasa.
String di sini adalah file biasa yang dibuat dalam sistem file yang di-mount. Shell membuat file dan mempertahankan deskriptornya sambil segera menghapus satu-satunya tautan sistem file (dan menghapusnya) sebelum ia menulis / membaca byte ke / dari file tersebut. Kernel akan mempertahankan ruang yang diperlukan untuk file sampai semua proses melepaskan semua deskriptor untuknya. Jika anak yang membaca dari deskriptor semacam itu memiliki kemampuan untuk melakukannya, ia dapat lseek()
diulang dengan dan dibaca lagi.
Dalam kedua kasus token <<<
dan |
mewakili file-deskriptor dan belum tentu file itu sendiri. Anda bisa mendapatkan ide yang lebih baik tentang apa yang terjadi dengan melakukan hal-hal seperti:
readlink /dev/fd/1 | cat
...atau...
ls -l <<<'' /dev/fd/*
Perbedaan yang paling signifikan antara kedua file adalah bahwa di sini-string / doc cukup banyak urusan yang terjadi sekaligus - shell menulis semua data ke dalamnya sebelum menawarkan deskriptor baca hingga kepada anak. Di sisi lain, shell membuka pipa pada deskriptor yang sesuai dan memotong anak-anak untuk mengelola mereka untuk pipa - dan karenanya ditulis / dibaca secara bersamaan di kedua ujungnya.
Namun, perbedaan ini umumnya hanya benar. Sejauh yang saya ketahui (yang sebenarnya tidak terlalu jauh) ini berlaku untuk hampir semua shell yang menangani <<<
short-hand di <<
sini untuk pengalihan dokumen di sini dengan pengecualian tunggal yash
. yash
, busybox
, dash
, Dan lainnya ash
varian cenderung kembali di sini-dokumen dengan pipa, meskipun, dan pada mereka kerang benar-benar ada sedikit perbedaan antara kedua setelah semua.
Oke - dua pengecualian. Sekarang saya berpikir tentang hal itu, ksh93
tidak benar-benar melakukan pipa sama sekali untuk |
, tetapi menangani seluruh bisnis w / soket - meskipun tidak melakukan file tmp yang dihapus <<<*
seperti kebanyakan orang lain. Terlebih lagi, itu hanya menempatkan bagian-bagian terpisah dari sebuah pipa di lingkungan subkulit yang merupakan semacam eufemisme POSIX untuk setidaknya itu bertindak seperti subkulit , dan bahkan tidak melakukan garpu.
Faktanya adalah bahwa patokan @ PSkocik (yang sangat berguna) hasil di sini dapat sangat bervariasi karena berbagai alasan, dan sebagian besar bergantung pada implementasi. Untuk pengaturan di sini-dokumen, faktor terbesar adalah tipe ${TMPDIR}
file-sistem target dan konfigurasi / ketersediaan cache saat ini, dan masih lebih banyak jumlah data yang akan ditulis. Untuk pipa itu akan menjadi ukuran proses shell itu sendiri, karena salinan dibuat untuk garpu yang diperlukan. Dengan cara bash
ini mengerikan pada pengaturan pipa (untuk memasukkan pergantian $(
perintah )
) - karena besar dan sangat lambat, tetapi dengan ksh93
itu hampir tidak ada perbedaan sama sekali.
Berikut cuplikan shell kecil lain untuk menunjukkan bagaimana shell membagi subkulit untuk sebuah pipa:
pipe_who(){ echo "$$"; sh -c 'echo "$PPID"'; }
pipe_who
pipe_who | { pipe_who | cat /dev/fd/3 -; } 3<&0
32059 #bash's pid
32059 #sh's ppid
32059 #1st subshell's $$
32111 #1st subshell sh's ppid
32059 #2cd subshell's $$
32114 #2cd subshell sh's ppid
Perbedaan antara apa pipelined pipe_who()
laporan panggilan dan laporan dari satu run di shell saat ini adalah karena (
subkulit ini )
perilaku tertentu mengklaim pid induk shell di $$
ketika diperluas. Meskipun bash
subkulit jelas merupakan proses yang terpisah, $$
parameter shell khusus bukan sumber informasi ini yang dapat diandalkan. Namun, sh
shell anak subkulit tidak menolak untuk melaporkannya secara akurat $PPID
.