Kadang-kadang proses substitusi tidak akan berfungsi seperti yang diharapkan. Berikut ini sebuah contoh:
Memasukkan:
gcc <(echo 'int main(){return 0;}')
Keluaran:
/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status
Memasukkan:
Tetapi berfungsi seperti yang diharapkan ketika digunakan dengan perintah yang berbeda:
grep main <(echo 'int main(){return 0;}')
Keluaran:
int main(){return 0;}
Saya telah memperhatikan kegagalan yang sama dengan perintah lain (yaitu perintah yang mengharapkan file dari proses substitusi tidak dapat digunakan /dev/fd/63
atau serupa). Kegagalan dengan gcc
ini adalah yang terbaru. Apakah ada beberapa aturan umum yang harus saya waspadai untuk menentukan kapan proses penggantian akan gagal dengan cara ini dan tidak boleh digunakan?
Saya menggunakan versi BASH ini di Ubuntu 12.04 (Saya juga melihat ini di arch dan debian):
GNU bash, versi 4.3.11 (1) -release (i686-pc-linux-gnu)
illegal seek
sepertinya jawabannya -|pipe
yangbash
menunjukkan program yang dijalankan bukan file yang bisa dicari. mungkin jika Anda tidak dapat berhasilecho data | command /dev/fd/0
di suatu program maka Anda akan memiliki keberuntungan yang sama dengan /<(cmd)
. Itu tidak menyediakan file pada disk - itu hanya menggantikan argumen yang menunjuk ke descriptor file pipa.gcc -xc <(echo 'int main(){return 0;}')
(yang mengatur bahasaC
secara eksplisit).Jawaban:
Proses subtitusi menghasilkan file khusus (seperti
/dev/fd/63
dalam contoh Anda) yang berperilaku seperti ujung baca dari pipa bernama. File ini dapat dibuka dan dibaca, tetapi tidak ditulis, tidak dicari.Perintah yang memperlakukan argumen mereka sebagai stream murni berfungsi sementara perintah yang berharap untuk mencari dalam file yang diberikan (atau menulis kepada mereka) tidak akan berfungsi. Jenis perintah yang akan bekerja adalah apa yang biasanya dianggap sebagai filter:
cat
,grep
,sed
,gzip
,awk
, dll ... Contoh perintah yang tidak akan bekerja adalah editor sepertivi
atau operasi file sepertimv
.gcc
ingin dapat melakukan akses acak pada file inputnya untuk mendeteksi bahasa apa yang mereka tulis. Jika Anda memberikangcc
petunjuk tentang bahasa file input, senang untuk melakukan streaming file:Bentuk yang lebih sederhana dan tanpa proses substitusi juga berfungsi:
Perhatikan bahwa ini tidak spesifik untuk
bash
. Semua shell yang mendukung substitusi proses berperilaku dengan cara yang sama.sumber
<()
Format harus bertindak seperti sebuah file untuk semua maksud dan tujuan. Bahkan, saya tidak tahu ada perintah yang mengharapkan file yang tidak akan senang<()
. Yang tidak berfungsi adalah mereka yang mengharapkan nama file , bukan file. Misalnya,grep -f
mengharapkan file dan berfungsi dengan baik<()
.<()
menghasilkan nama file (konstruk memperluas ke/proc/self/fd/something
sistem saya). Nama ini, ketika dibuka, bertindak seperti ujung baca dari pipa bernama (S_IFIFO
) daripada file biasa (S_IFREG
) di yang mendukungread()
dan lain-lain tetapi tidakseek()
.zsh
mendukung bentuk substitusi proses ke-3 yang menggunakan file sementara terutama untuk tujuan itu:gcc =(echo 'int main(){return 0;}')
<(echo '...')
tetapi tidak dengan<(git show ...)
. tahu mengapa itu bisa terjadi?ld
(yang mendeteksi format objek).-x
bukan sebuah petunjuk; itu adalah deklarasi. Jika Anda menentukan-x f95
, GCC akan meneruskan file ke kompiler Fortran-95 terlepas dari nama atau isinya. Lihat gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Overall-Options.html