Pada OS X, seperti pada semua sistem di mana mereka didukung kecuali Linux , pembukaan /dev/fd/x
adalah seperti melakukan a dup(x)
, fd yang dihasilkan lebih atau kurang menunjuk ke deskripsi file terbuka yang sama seperti pada fd x dan khususnya akan memiliki offset yang sama dalam file.
Linux adalah pengecualian di sini. Di Linux, /dev/fd/x
adalah symlink ke /proc/self/fd/x
dan /proc/self/fd/x
merupakan pseudo-symlink ke file yang terbuka di fd x. Di Linux saat Anda melakukan open("/dev/fd/x", somemode)
, Anda mendapatkan deskripsi file terbuka baru ke file yang sama seperti buka x
. Fd baru yang Anda peroleh tidak terkait dengan fd x dengan cara apa pun. Secara khusus, offset akan berada di awal file (kecuali jika Anda membukanya O_APPEND
tentu saja) dan mode (baca / tulis / tambahkan ...) dapat berbeda dari yang ada di fd x (Anda bahkan bisa mendapatkan sesuatu yang sangat berbeda dari apa yang ada di fd x, seperti ujung pipa saat membukanya dalam mode yang berlawanan). (Itu juga berarti bahwa itu tidak berfungsi untuk soket misalnya yang Anda tidak dapat membuka () ).
Jadi, di Linux, ketika Anda melakukannya
exec 5<> file
echo test >&5
Offset fd 5 ada di akhir file. Jika kamu melakukan
cat <&5
Anda tidak mendapat apa-apa.
Masih ketika Anda melakukannya:
cat /dev/fd/5
Anda lihat test
karena cat
mendapat read-only fd baru untuk file
tidak terkait dengan fd 5.
Pada sistem lain, setelah
cat /dev/fd/5
cat
mendapat fd yang merupakan duplikat dari fd 5, jadi masih dengan offset di akhir file.
Alasan mengapa ia bekerja less
adalah karena suatu alasan, less
melakukan a lseek()
pada fd ke awal file (apakah lseek(1); lseek(0)
untuk menentukan apakah file tersebut dapat dicari atau tidak).
Di sini, Anda mungkin ingin memiliki fd untuk membaca dan satu untuk menulis jika Anda ingin keduanya memiliki offset yang berbeda:
exec 5< file 9>&1 > file
Atau Anda harus membuka kembali file jika masih ada, atau melakukan lseek()
seperti yang less
dilakukannya.
ksh93
dan zsh
satu-satunya cangkang dengan lseek()
operator bawaan :
cat <&5 <#((0)) # ksh93
{sysseek 0; cat} <&5 # zsh, zmodload zsh/system to enable that builtin
Atau:
cat /dev/fd/5 5<#((0)) # ksh93
sysseek -u 5 0; cat /dev/fd/5 # zsh