Estoy tratando de emular el proceso de resolución de ruta (consulte la página de manual path_resolution) en sistemas similares a Unix.
Mi sistema operativo es Linux con GNU coreutils 8.7.
Para aclarar el significado de '/' adicional en resolución, hice lo siguiente en un shell:
mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link
Todo estuvo bien, porque this_is_link es un enlace simbólico, y simplemente lo eliminé. Pero al intentarlo:
mkdir this_is_dir
ln -s this_is_dir this_is_link
rm this_is_link/
Se hizo eco rm: cannot remove 'this_is_link/': Is a directory
Bueno, el final '/' causó el seguimiento del enlace simbólico, pensé. Entonces, probé otro comando:rmdir this_is_link/
Y salió un resultado divertido: rmdir: failed to remove 'this_is_link/': Not a directory
No es lo que esperaba. Entonces le pedí a mi amigo que confirmara si se podía obtener el mismo resultado en su sistema. Tenía una versión de coreutils más baja que yo. Y el resultado fue sorprendente, no importa rm
o rmdir 'this_is_link/'
, se Not a directory
produce el mismo error .
Y otro amigo acaba de probarlo en su Mac OS, el resultado es: rm
=> 'Es un directorio', rmdir
=> el directorio se eliminó con éxito, el enlace permaneció .
¿Hay alguna especificación sobre el comportamiento exacto de la resolución de ruta?
Respuestas:
La especificación POSIX / Single Unix especifica que un nombre de ruta con una barra inclinada final debe referirse a un directorio (ver definiciones base §4.11 resolución de nombre de ruta ).
foo/
de hecho se define como equivalente afoo/.
(para propósitos de resolución de ruta, no cuando se manipulan nombres de archivos;basename
edirname
ignora las barras diagonales finales). La mayoría de las implementaciones respetan esto, pero hay algunas excepciones.Esto explica el comportamiento de
rm this_is_link/
: es equivalente arm this_is_link/.
, donde el argumento es claramente un directorio.rmdir this_is_link/
debería referirse de manera similar al directorio. Que no lo haga en su máquina es un error en GNU coreutils. OSX se está comportando correctamente aquí.fuente
Mi toma:
Por cierto, la resolución de ruta tiene muy poco que ver con esto, solo parece estar '' rm '' cortando una esquina en lugar de (correctamente) invocar "stat" en un argumento (que es lo que está haciendo rmdir).
Salud.
fuente
rm
llama a stat (bueno, newfstatat, en realidad, con laAT_SYMLINK_NOFOLLOW
opción) y se niega a continuar, mientras que rmdir realmente llama a rmdir (2), pero obtieneENOTDIR
.AT_SYMLINK_NOFOLLOW
evitará que siga el enlace simbólico, por lo que rm debería eliminar el enlace en lugar de imprimir "No es un directorio" que no coincide con la circunstancia.stat
ystat -L
difiere solo si el argumento se proporciona sin una barra inclinada final.rm
se comporta correctamente yrmdir
no lo es. El seguimiento/
debe obligarlos a tratar su argumento como un directorio, según el estándar POSIX. Vea mi respuesta para referencias .