Sebagian besar perintah memiliki saluran input tunggal (input standar, deskriptor file 0) dan saluran output tunggal (output standar, deskriptor file 1) atau beroperasi pada beberapa file yang dibuka sendiri (sehingga Anda memberikan mereka nama file). (Itu selain dari kesalahan standar (fd 2), yang biasanya memfilter semua jalan ke pengguna.) Namun kadang-kadang nyaman untuk memiliki perintah yang bertindak sebagai filter dari beberapa sumber atau ke beberapa target. Misalnya, inilah skrip sederhana yang memisahkan baris bernomor ganjil dalam file dari yang genap bernomor
while IFS= read -r line; do
printf '%s\n' "$line"
if IFS= read -r line; then printf '%s\n' "$line" >&3; fi
done >odd.txt 3>even.txt
Sekarang anggaplah Anda ingin menerapkan filter yang berbeda untuk garis bilangan ganjil dan ke garis genap (tetapi tidak menyatukannya kembali, itu akan menjadi masalah yang berbeda, tidak layak dari shell pada umumnya). Dalam shell, Anda hanya bisa menyalurkan output standar perintah ke perintah lain; untuk mem-pipe deskriptor file lain, Anda harus mengarahkannya ke fd 1 terlebih dahulu.
{ while … done | odd-filter >filtered-odd.txt; } 3>&1 | even-filter >filtered-even.txt
Kasus penggunaan lain yang lebih sederhana adalah memfilter output kesalahan dari suatu perintah .
exec M>&N
mengarahkan kembali deskriptor file ke yang lain untuk sisa skrip (atau sampai perintah lain mengubah deskriptor file lagi). Ada beberapa fungsi yang tumpang tindih antara exec M>&N
dan somecommand M>&N
. The exec
bentuk lebih kuat dalam hal itu tidak harus bersarang:
exec 8<&0 9>&1
exec >output12
command1
exec <input23
command2
exec >&9
command3
exec <&8
Contoh lain yang mungkin menarik:
Dan untuk lebih banyak contoh:
NB Ini adalah pertanyaan mengejutkan yang berasal dari penulis pos paling terunggah di situs yang menggunakan pengalihan melalui fd 3 !
while IFS= read -r line;
? Cara saya melihatnya, IFS tidak berpengaruh di sini karena Anda menetapkan nilai hanya satu variabel ( baris ). Lihat pertanyaan ini.IFS
membuat perbedaan bahkan jika Anda membaca variabel tunggal (itu untuk mempertahankan spasi putih terkemuka).sed -ne 'w odd.txt' -e 'n;w even.txt'
?Berikut ini contoh menggunakan FD tambahan sebagai kontrol obrolan script bash:
sumber
Dalam konteks pipa bernama (fifos) penggunaan deskriptor file tambahan dapat mengaktifkan perilaku perpipaan yang tidak memblokir.
Lihat: Named Pipe ditutup sebelum waktunya dalam skrip?
sumber
Deskriptor file tambahan baik untuk ketika Anda ingin menangkap stdout dalam variabel namun masih ingin menulis ke layar, misalnya dalam antarmuka pengguna skrip bash
sumber
Berikut ini skenario lain ketika menggunakan deskriptor file tambahan yang tampaknya sesuai (dalam Bash):
Keamanan kata sandi shell script parameter baris perintah
sumber
Contoh: menggunakan kawanan untuk memaksa skrip dijalankan secara seri dengan kunci file
Salah satu contoh adalah dengan menggunakan penguncian file untuk memaksa skrip untuk menjalankan sistem seri lebar. Ini berguna jika Anda tidak ingin dua skrip dari jenis yang sama beroperasi pada file yang sama. Jika tidak, kedua skrip akan saling mengganggu dan kemungkinan data korup.
Gunakan kawanan secara fungsional dengan mendefinisikan kunci dan membuka kunci
Anda juga dapat menggunakan logika penguncian / penguncian ini menjadi fungsi yang dapat digunakan kembali.
trap
Shell bawaan berikut akan secara otomatis melepaskan kunci file ketika skrip keluar (kesalahan atau berhasil).trap
membantu membersihkan kunci file Anda. Path/tmp/file.lock
harus berupa jalur kode keras sehingga banyak skrip dapat mencoba untuk menguncinya.The
unlock
logika di atas adalah untuk menghapus file sebelum mengunci dilepaskan. Dengan cara ini membersihkan file kunci. Karena file itu dihapus, contoh lain dari program ini dapat memperoleh kunci file.Penggunaan fungsi kunci dan buka kunci dalam skrip
Anda dapat menggunakannya dalam skrip Anda seperti contoh berikut.
Jika Anda ingin kode Anda menunggu hingga dapat mengunci, Anda dapat menyesuaikan skrip seperti:
sumber
Sebagai contoh konkret, saya hanya menulis sebuah skrip yang memerlukan informasi waktu dari sebuah sub-perintah. Menggunakan deskriptor file tambahan memungkinkan saya untuk menangkap
time
stderr perintah tanpa mengganggu stdout atau stderr subcommand.Apa yang dilakukan adalah mengarahkan
ls
stderr ke fd 3, mengarahkan fd 3 ke stderr skrip, dan mengarahkantime
stderr ke sebuah file. Ketika skrip dijalankan, stdout dan stderr-nya sama dengan sub-perintah, yang dapat dialihkan seperti biasa. Hanyatime
keluaran yang diarahkan ke file.sumber