Esta es una pregunta adicional que comenzó con esta: ¿Cómo editar enlaces simbólicos en OS X?
Ahora que sé cómo editar la ruta a la que apuntan los enlaces simbólicos, estoy tratando de averiguar cómo hacerlo recursivamente para cualquier enlace simbólico roto. Soy un tipo de PHP, por lo que esto de la CLI es algo extraño para mí...
Parece que hay algunos elementos específicos para esto, a saber:
El primero es bastante fácil:
find /path/to/search -type l | while read f; do if [ ! -e "$f" ]; then ls -l "$f"; fi; done
Esto me da una buena lista de todos los enlaces simbólicos rotos que se encuentran debajo del directorio proporcionado. Pero creo que necesitaría almacenar la ubicación de cada uno en una variable (¿matriz?) Para trabajar con ella.
A continuación, parece que cambiar la acción suministrada en la parte "entonces" de la lógica daría lugar a la solución.
El artículo 2 se puede recuperar usando:
readlink /path/to/broken/symlink
Así que parece que tenemos que meter eso en una variable. No tengo claro cómo hacer esto en la terminal.
El número 3 sería una simple edición de la ruta recuperada durante el paso 2. Necesito reemplazar el nombre de la unidad anterior por el nuevo. Entonces cambiando:
/Volumes/Old\ Drive/path/to/symlink
a
/Volumes/New\ Drive/path/to/symlink
Tampoco está claro exactamente cómo hacer esto dentro de un script CLI. Parece que se necesita algún tipo de reemplazo de cadena. Algo así como str_replace en el mundo de PHP.
Finalmente, el paso 4 se puede hacer a través de:
ln -f -s /path/to/new/location/of/original /path/to/location/of/broken/symlink/
como se detalla en mi otra pregunta, previamente vinculada anteriormente.
¿Cómo uniría exactamente estos conceptos para lograr el resultado deseado de arreglar todos mis enlaces simbólicos de una sola vez?
Desde la parte superior de mi cabeza (y sin ninguna prueba):
Cree un archivo de texto con el siguiente contenido
#!/bin/bash
find "$1" -type l | while read symlink; do
if [ ! -e "$symlink" ]; then
old_path=$(readlink "$symlink")
new_path=${old_path/Old Drive/New Drive}
ln -f -s "$new_path" "$symlink"
fi
done
Hazlo ejecutable ejecutandochmod +x name-of-file
./name-of-file /path/to/search
Esto no se ha probado , así que pruébelo primero con un directorio de muestra.
Para agregar algunas explicaciones
old_path=$(readlink "$symlink")
ejecuta el comando $(...)
y asigna el resultado a$old_path
${old_path/Old Drive/New Drive}
hace sustitución de texto en$old_path
En un bash
shell, para establecer una variable, simplemente use set NAME=bob
o set VITAL_SIGNS=none
.
También puede establecer una variable utilizando la salida de un comando llamando a la bash
función incorporada read
para asignar la salida a una variable con nombre. Esto funciona bien en un flujo de tubería como este:
ls -l | wc -l | read NUMBER_OF_LINES
O puede asignar la salida directamente a una variable así:
LICENSE_KEY=$(cat ~/software/key.txt | grep KEY | awk '{print $1}')
Una excelente manera de leer variables recursivamente es en un bucle de la siguiente manera:
for BROKEN_LINK in $(commands to produce a list of files)
do
commands here to sort your links out, noting that the broken links are stored in the variable $BROKEN_LINKS
done
Con lo anterior en mente, algo como lo siguiente debería funcionar:
probar que una carpeta no existe
StuffeMac:dan stuffe$ ls ~/Desktop/broken_links
ls: /Users/stuffe/Desktop/broken_links: No such file or directory
probar que existe una nueva carpeta de destino
StuffeMac:dan stuffe$ ls ~/Desktop/working_links
StuffeMac:dan stuffe$
crear algunos enlaces no válidos y válidos
StuffeMac:dan stuffe$ ln -s ~/Desktop/brokenlinks/dan1
StuffeMac:dan stuffe$ ln -s ~/Desktop/brokenlinks/dan2
StuffeMac:dan stuffe$ ln -s ~/Desktop/working_links/dan3
StuffeMac:dan stuffe$ ln -s ~/Desktop/outofscopedeadlinks/dan4
StuffeMac:dan stuffe$ ls -l
total 32
lrwxr-xr-x 1 stuffe staff 38 8 Dec 10:06 dan1 -> /Users/stuffe/Desktop/brokenlinks/dan1
lrwxr-xr-x 1 stuffe staff 38 8 Dec 10:06 dan2 -> /Users/stuffe/Desktop/brokenlinks/dan2
lrwxr-xr-x 1 stuffe staff 40 8 Dec 10:06 dan3 -> /Users/stuffe/Desktop/working_links/dan3
lrwxr-xr-x 1 stuffe staff 46 8 Dec 10:21 dan4 -> /Users/stuffe/Desktop/outofscopedeadlinks/dan4
tome una lista de enlaces muertos en un archivo para la entrada
StuffeMac:dan stuffe$ find . -type l | while read f; do if [ ! -e "$f" ]; then ls "$f" >> deadlinks.txt; fi; done
StuffeMac:dan stuffe$ more deadlinks.txt
./dan1
./dan2
./dan4
ejecutar un bucle contra cada enlace muerto
StuffeMac:dan stuffe$ for DEAD_LINK in $(cat deadlinks.txt)
> do
> DESTINATION_IN_SCOPE=$(readlink $DEAD_LINK | grep brokenlinks | wc -l)
> NEW_DESTINATION="~/Desktop/working_links/"
> if [ $DESTINATION_IN_SCOPE = "1" ]
> then
> NEW_LINK=$(echo $DEAD_LINK | colrm 1 2)
> ln -f -s $NEW_DESTINATION$NEW_LINK $DEAD_LINK
> else
> echo "Link $DEAD_LINK not in target folder"
> fi
> done
Link ./dan4 not in target folder
StuffeMac:dan stuffe$
echa un vistazo a los enlaces simbólicos después de las ediciones
StuffeMac:dan stuffe$ ls -l
total 32
lrwxr-xr-x 1 stuffe staff 28 8 Dec 10:08 dan1 -> ~/Desktop/working_links/dan1
lrwxr-xr-x 1 stuffe staff 28 8 Dec 10:08 dan2 -> ~/Desktop/working_links/dan2
lrwxr-xr-x 1 stuffe staff 40 8 Dec 10:06 dan3 -> /Users/stuffe/Desktop/working_links/dan3
lrwxr-xr-x 1 stuffe staff 46 8 Dec 10:21 dan4 -> /Users/stuffe/Desktop/outofscopedeadlinks/dan4
bash
de obtener resultados de los comandos es usar la $(command)
sintaxis like for MYVAR in $(ls | grep somefilter)
en lugar de usar acentos graves. Tiene algunas ventajas sobre los acentos graves como este . Hice ediciones basadas en esto.
JVC
Run: Command not found
sin ladera
ian c
bash
de sintaxis nueva de este. ¡Así que un voto positivo por eso! ¡Gracias!JVC
sin ladera
new_path=
línea. Si agrega una muestra real de su ruta anterior y nueva, puedo ajustar el script en consecuencia.JVC
JVC