¿Algún sistema operativo proporciona un mecanismo (llamada al sistema, no un programa de línea de comando) para cambiar el nombre de ruta al que hace referencia un enlace simbólico (enlace simbólico), aparte de desvincular el antiguo y crear uno nuevo?
El estándar POSIX no. Solaris 10 no lo hace. MacOS X 10.5 (Leopard) no. (Estoy bastante seguro de que ni AIX ni HP-UX tampoco. A juzgar por esta lista de llamadas al sistema Linux, Linux tampoco tiene esa llamada al sistema).
¿Hay algo que haga?
(Espero que la respuesta sea "No").
Como probar que un negativo es difícil, reorganicemos la pregunta.
Si sabe que algunos sistemas operativos (similares a Unix) que no figuran en la lista no tienen ninguna llamada al sistema para reescribir el valor de un enlace simbólico (la cadena devuelta por readlink()
) sin eliminar el enlace simbólico anterior y crear uno nuevo, agréguelo, o ellos. en una respuesta
ln
comando (o la API equivalente) sobrescribiendo el enlace anterior? ¿Qué problema estás teniendo?Respuestas:
AFAIK, no, no puedes. Tienes que eliminarlo y recrearlo.En realidad, puede sobrescribir un enlace simbólico y así actualizar el nombre de ruta al que hace referencia:EDITAR : Como el OP señaló en un comentario, el uso de la
--force
opción hará que seln
realice una llamada al sistemaunlink()
antessymlink()
. A continuación, la salida destrace
mi caja de Linux lo demuestra:Así que supongo que la respuesta final es "no".EDITAR : Lo siguiente se copia de la respuesta de Arto Bendiken en unix.stackexchange.com, alrededor de 2016.
De hecho, esto se puede hacer atómicamente
rename(2)
, primero creando el nuevo enlace simbólico con un nombre temporal y luego sobrescribiendo limpiamente el enlace simbólico anterior de una sola vez. Como dice la página del manual :En el shell, haría esto de la
mv -T
siguiente manera:Puede
strace
usar ese último comando para asegurarse de que realmente se está utilizandorename(2)
debajo del capó:Tenga en cuenta que en lo anterior, ambos
mv -T
ystrace
son específicos de Linux.En FreeBSD, use
mv -h
alternativamente.Nota del editor: así es como Capistrano lo ha hecho durante años, desde ~ 2.15. Ver esta solicitud de extracción .
fuente
¡Sí tu puedes!
fuente
-f
opción significa 'eliminar el destino existente' antes de crear el nuevo. Entonces, este comando logra el resultado, pero al hacerlounlink(2)
seguido desymlink(2)
. De esto no se trataba la pregunta original. También tenga en cuenta que la respuesta aceptada y la siguiente respuesta más votada se utilizanln -sf
para hacer el trabajo, pero como lostrace
muestra el resultado, lo haceunlink()
ysymlink()
porque no hay una llamada al sistema para modificar un enlace simbólico.No es necesario desvincular explícitamente el antiguo enlace simbólico. Puedes hacerlo:
(o use el enlace simbólico equivalente y cambie el nombre de las llamadas). Esto es mejor que desvincular explícitamente porque el cambio de nombre es atómico, por lo que puede estar seguro de que el enlace siempre apuntará al objetivo antiguo o al nuevo. Sin embargo, esto no reutilizará el inodo original.
En algunos sistemas de archivos, el objetivo del enlace simbólico se almacena en el inodo mismo (en lugar de la lista de bloqueo) si es lo suficientemente corto; Esto se determina en el momento en que se crea.
Con respecto a la afirmación de que el propietario y el grupo reales son irrelevantes, el enlace simbólico (7) en Linux dice que hay un caso en el que es significativo:
fuente
set -x -e; mkdir junk; ( cd junk; mkdir olddir newdir; ln -s olddir mylink; ls -ilR; ln -s newdir temp; ls -ilR; mv temp mylink; ls -ilR; ); rm -fr junk
. Si crea archivos oldfile y newfile en lugar de directorios y ejecuta el script equivalente (principalmente cambiando olddir a oldfile, newdir a newfile), obtendrá el efecto que esperaba. ¡Solo una complejidad extra! Gracias por la respuesta.Solo una advertencia a las respuestas correctas anteriores:
El uso del método -f / --force proporciona un riesgo de perder el archivo si mezcla origen y destino:
Por supuesto, esto es lo que se pretende, pero generalmente ocurren errores. Entonces, eliminar y reconstruir el enlace simbólico es un poco más trabajo pero también un poco más ahorrador:
que al menos guarda mi archivo.
fuente
-f
u--force
siempre es un poco peligroso; supone que el usuario sabe de qué se trata. Es doblemente letal si lo usa habitualmente (rm -fr …
cada vez es peligroso).¿No lo desvincularía y crearía uno nuevo, al final, haría lo mismo?
fuente
ln --force
comando sobrescribirá absolutamente un enlace existente.ln (1)
, mientras que Matt b. está discutiendo el hecho de quesymlink (2)
no no admite sobreescritura. Ambos tienen razón, y sugeriría que observar la implementación deln (1)
sería la forma más idónea de lograr el procedimiento de desvinculación de enlaces.Por si acaso ayuda: hay una manera de editar un enlace simbólico con Midnight Commander (MC). El comando de menú es (en francés en mi interfaz mc):
que puede traducirse a:
El atajo es Cx Cs
Quizás internamente usa el
ln --force
comando, no lo sé.Ahora, estoy tratando de encontrar una manera de editar una gran cantidad de enlaces simbólicos a la vez (así es como llegué aquí).
fuente
unlink()
seguido de unsymlink()
, simplemente porque eso es lo que proporcionan los sistemas tipo Unix.Técnicamente, no hay un comando incorporado para editar un enlace simbólico existente. Se puede lograr fácilmente con unos pocos comandos cortos.
Aquí hay una pequeña función bash / zsh que escribí para actualizar un enlace simbólico existente:
fuente
unlink()
ysymlink()
con el nuevo valor, que es lo que sucede detrás de escena con su código. Personalmente, quisiera que la función insista en exactamente dos (o tal vez un múltiplo de dos) argumentos y rescate si la invocación no es correcta. Sin embargo, esa es una perspectiva particular.