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/x
giố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/x
là một liên kết tượng trưng đến /proc/self/fd/x
và /proc/self/fd/x
là 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_APPEND
khó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 test
bởi vì cat
có một fd chỉ đọc mới file
khô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 less
là vì một số lý do, less
thự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ư less
vậy.
ksh93
và zsh
là 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