Hari ini saya belajar sesuatu tentang fifo dengan artikel ini: Pengantar Named Pipes , yang menyebutkan cat <(ls -l)
.
Saya melakukan beberapa percobaan dengan menggunakan sort < (ls -l)
, yang muncul kesalahan:
-bash: syntax error near unexpected token `('`
Kemudian saya menemukan saya salah menambahkan ruang ekstra dalam perintah.
Tapi, mengapa perintah tambahan ini akan menyebabkan kegagalan ini? Mengapa simbol pengalihan harus dekat dengan (
?
Jawaban:
Karena itu bukan
<
, itu<()
yang sangat berbeda. Ini disebut proses substitusi , ini adalah fitur dari cangkang tertentu yang memungkinkan Anda untuk menggunakan output dari satu proses sebagai input untuk yang lain.The
>
dan<
operator redirect output ke dan masukan dari file . The<()
Operator berkaitan dengan perintah (proses), bukan file. Ketika Anda berlariAnda mencoba menjalankan perintah
ls
dalam sebuah subkulit (itulah arti tanda kurung), lalu meneruskan subkulit tersebut sebagai file inputsort
. Namun, ini tidak menerima sintaksis dan Anda mendapatkan kesalahan yang Anda lihat.sumber
then sort is attempting to read the subshell as its input file
→ ini jelas salah, karena Bash bahkan tidak akan menguraikan sintaks. Baikls
tidaksort
benar-benar dijalankan.< (ls)
bukan token yang valid di sini.(ls)
akan berjalanls
dalam subkulit.Karena memang begitulah seharusnya.
<(...)
inbash
adalah sintaks untuk substitusi proses. Ini disalin dari operator yang sama diksh
.<
,(
,)
,|
,&
,;
Adalah token leksikal khusus dibash
yang digunakan untuk membentuk operator khusus dalam kombinasi yang berbeda.<
,<(
,<<
,<&
... masing-masing memiliki peran mereka.<
adalah untuk pengalihan.<file
,< file
akan mengarahkan input dari file.<'(file)'
akan mengarahkan input dari file yang dipanggil(file)
, tetapi<(file)
merupakan operator berbeda yang bukan merupakan operator redirection.< (file)
akan<
diikuti oleh(file)
. Dalam konteks itu, dalambash
,(file)
tidak valid.(...)
dapat valid sebagai token tunggal dalam beberapa konteks seperti:Tapi tidak di
Dalam
fish
shell, ini berbeda. Infish
,(...)
adalah untuk substitusi perintah (setara dengan$(...)
inbash
). Dan<
untuk pengalihan input seperti di shell Bourne-like.Jadi di
fish
:akan sama dengan:
Itu adalah:
Tapi itu sesuatu yang sama sekali berbeda dari
bash
proses substitusi.Dalam
yash
shell, shell POSIX lain,<(...)
bukan untuk substitusi proses tetapi untuk pengalihan prosesDi sana,
Pendek untuk:
adalah operator pengalihan. Ini kurang lebih setara dengan:
Sementara di
bash
,<(ls -l)
diperluas ke jalur pipa, jadi itu lebih seperti:Dalam
zsh
,(...)
kelebihan beban sebagai operator globbing ((*.txt|*.png)
akan diperluas ketxt
danpng
file) dan sebagai kualifikasi glob (*(/)
misalnya diperluas ke file direktori).Di
zsh
, di:Itu
(ls -l)
akan diperlakukan sebagai kualifikasi glob. Thel
gumpal kualifikasi adalah untuk mencocokkan pada jumlah link dan mengharapkan angka setelahl
(seperti dalamls -ld ./*(l2)
akan daftar file dengan 2 link), sehingga ini mengapa Anda mendapatkanzsh: number expected
kesalahan di sana.sort < (w)
akan memberikanzsh: no matches found: (w)
kesalahan sebagai gantinya(w)
cocok dengan file dengan nama kosong yang dapat ditulisi.sort < (w|cat)
akan mengurutkan kontenw
dan / ataucat
file di direktori saat ini ...sumber
sort < $(ls -l)
memberikan kesalahan ini:bash: $(ls -l): ambiguous redirect
$(ls -l)
diperluas hingga lebih dari satu kata. Gunakan tanda kutip untuk mencegah split + glob (sort < "$(echo file)"
). Perhatikan bahwa perilaku ataubash
berbeda dari POSIX sh dalam bash apakah itu membagi + glob di sana juga ketika non-interaktif (bukan ketika dipanggil seolah-sh
olah).ls -l | sort /dev/fd/0
saya dapat mengatakan bahwa outputls -l
disimpan/dev/fd/0
dansort
perintah membacanya untuk memberikan output yang diinginkan. Saya menggunakantail -f --retry /dev/fd/0
untuk memonitor file itu tetapi saya tidak mendapatkan output apa pun. Mengapa? bagaimana saya bisa membaca file itu?(foo | psub)
untuk mencapai substitusi proses input; belum ada pengganti (ha) untuk substitusi proses keluaran.