Trên OS X, giống như trên tất cả các hệ thống mà chúng được hỗ trợ ngoại trừ Linux , việc mở /dev/fd/xgiống như thực hiện a dup(x), kết quả fd ít nhiều điểm cho cùng một mô tả tệp mở như trên fd x và đặc biệt sẽ có cùng độ lệch trong tệp.
Linux là ngoại lệ ở đây. Trên Linux, /dev/fd/xlà một liên kết tượng trưng đến /proc/self/fd/xvà /proc/self/fd/xlà một liên kết giả đối với tệp đang mở trên fd x. Trên Linux khi bạn thực hiện open("/dev/fd/x", somemode), bạn nhận được một mô tả tệp mở hoàn toàn mới cho cùng một tệp như mở trên x. Fd mới mà bạn có được không liên quan đến fd x dưới bất kỳ hình thức nào. Cụ thể, phần bù sẽ nằm ở phần đầu của tệp (trừ khi bạn mở bằng O_APPENDkhóa học) và chế độ (đọc / ghi / nối ...) có thể khác với phần trên fd x (thậm chí bạn có thể nhận được một cái gì đó hoàn toàn khác với những gì trên fd x, như đầu kia của ống khi mở nó ở chế độ ngược lại). (Điều đó cũng có nghĩa là nó không hoạt động đối với các socket chẳng hạn mà bạn không thể mở () ).
Vì vậy, trên Linux, khi bạn làm
exec 5<> file
echo test >&5
Phần bù của fd 5 nằm ở cuối tập tin. Nếu bạn làm
cat <&5
Bạn không nhận được gì.
Vẫn khi bạn làm:
cat /dev/fd/5
Bạn thấy testbởi vì catcó một fd chỉ đọc mới filekhông liên quan đến fd 5.
Trên các hệ thống khác, khi
cat /dev/fd/5
cat nhận được một fd là bản sao của fd 5, do đó, vẫn có phần bù ở cuối tệp.
Lý do tại sao nó hoạt động lesslà vì một số lý do, lessthực hiện một lseek()fd đó vào đầu tập tin ( lseek(1); lseek(0)để xác định xem tập tin có thể tìm kiếm được hay không).
Ở đây, bạn có thể muốn có một fd để đọc và một để viết nếu bạn muốn cả hai có độ lệch khác nhau:
exec 5< file 9>&1 > file
Hoặc bạn sẽ phải mở lại tệp nếu vẫn ở đó hoặc làm lseek()như lessvậy.
ksh93và zshlà các shell duy nhất có lseek()toán tử dựng sẵn :
cat <&5 <#((0)) # ksh93
{sysseek 0; cat} <&5 # zsh, zmodload zsh/system to enable that builtin
Hoặc là:
cat /dev/fd/5 5<#((0)) # ksh93
sysseek -u 5 0; cat /dev/fd/5 # zsh