En OS X, como en todos los sistemas donde son compatibles, excepto Linux , la apertura /dev/fd/x
es como hacer una dup(x)
, el fd resultante apunta más o menos a la misma descripción de archivo abierto que en fd x y en particular tendrá el mismo desplazamiento dentro del archivo.
Linux es la excepción aquí. En Linux, /dev/fd/x
es un enlace simbólico /proc/self/fd/x
y /proc/self/fd/x
es un pseudo-enlace simbólico al archivo abierto en fd x. En Linux cuando hace una open("/dev/fd/x", somemode)
, obtiene una nueva descripción de archivo abierto para el mismo archivo que abierto en x
. El nuevo fd que obtenga no está relacionado con fd x de ninguna manera. En particular, el desplazamiento estará al comienzo del archivo (excepto si lo abre, por O_APPEND
supuesto) y el modo (lectura / escritura / anexar ...) puede ser diferente del de fd x (incluso puede obtener algo bastante diferente de lo que está en fd x, como el otro extremo de la tubería al abrirlo en el modo opuesto). (Eso también significa que eso no funciona para sockets, por ejemplo, que no puedes abrir () ).
Entonces, en Linux, cuando lo haces
exec 5<> file
echo test >&5
El desplazamiento del fd 5 está al final del archivo. Si lo haces
cat <&5
No consigues nada.
Aún cuando lo haces:
cat /dev/fd/5
Verá test
porque cat
obtiene un nuevo fd de solo lectura que file
no está relacionado con fd 5.
En otros sistemas, sobre
cat /dev/fd/5
cat
obtiene un fd que es un duplicado de fd 5, por lo que aún con un desplazamiento al final del archivo.
La razón por la que funciona less
es que, por alguna razón, less
hace un lseek()
f en ese fd al comienzo del archivo (hace un lseek(1); lseek(0)
para determinar si el archivo es buscable o no).
Aquí, probablemente desee tener un fd para leer y uno para escribir si desea que ambos tengan diferentes compensaciones:
exec 5< file 9>&1 > file
O tendrá que volver a abrir el archivo si todavía está allí, o hacer lseek()
lo less
mismo.
ksh93
y zsh
son las únicas conchas con un lseek()
operador incorporado :
cat <&5 <#((0)) # ksh93
{sysseek 0; cat} <&5 # zsh, zmodload zsh/system to enable that builtin
O:
cat /dev/fd/5 5<#((0)) # ksh93
sysseek -u 5 0; cat /dev/fd/5 # zsh