У OS X, як і у всіх системах, де вони підтримуються, окрім Linux , відкриття /dev/fd/x- це як робити dup(x), в результаті fd більш-менш вказує на той самий опис відкритого файлу, що і на fd x, і, зокрема, матиме однаковий зсув у файлі.
Тут є виключенням Linux. В Linux /dev/fd/xє символьним посиланням на /proc/self/fd/xі /proc/self/fd/xє псевдосимвольним посиланням на файл, відкритий на fd x. У Linux, коли ви робите open("/dev/fd/x", somemode), ви отримуєте абсолютно новий відкритий опис файлу до того ж файлу, що і відкритий на x. Отриманий вами новий fd жодним чином не пов'язаний з fd x. Зокрема, зсув буде на початку файлу (за винятком випадків, якщо ви відкриваєте його O_APPENDзвичайно), а режим (читання / запис / додавання ...) може відрізнятися від режиму на fd x (ви навіть можете отримати щось зовсім інше, ніж те, що на fd x, як і інший кінець труби при відкриванні її в протилежному режимі). (Це також означає, що це не працює для розеток, наприклад, які ви не можете відкрити () ).
Отже, в Linux, коли ви це робите
exec 5<> file
echo test >&5
Зсув fd 5 знаходиться в кінці файлу. Якщо ти зробиш
cat <&5
Ви нічого не отримуєте.
Тим не менше, коли ти робиш:
cat /dev/fd/5
Ви бачите, testтому що catотримує новий fd лише для читання, який fileне має відношення до fd 5.
На інших системах, на
cat /dev/fd/5
cat отримує fd, який є дублікатом fd 5, тому все-таки зі зміщенням в кінці файлу.
Причина, з якою вона працює, lessполягає в тому, що з якоїсь причини lessробить lseek()на цьому fd початок файлу (чи lseek(1); lseek(0)визначає, чи файл можна шукати чи ні).
Тут ви, мабуть, хочете мати FD для читання та один для написання, якщо ви хочете, щоб обидва мали різні компенсації:
exec 5< file 9>&1 > file
Або вам доведеться знову відкрити файл, якщо він все ще є, або зробіть так, lseek()як lessце робиться.
ksh93і zshце єдині оболонки із вбудованим lseek()оператором:
cat <&5 <#((0)) # ksh93
{sysseek 0; cat} <&5 # zsh, zmodload zsh/system to enable that builtin
Або:
cat /dev/fd/5 5<#((0)) # ksh93
sysseek -u 5 0; cat /dev/fd/5 # zsh