Come modificare ricorsivamente il percorso dei collegamenti simbolici?

4

Questa è una domanda aggiuntiva che è iniziata con questo - Come modificare i collegamenti simbolici in OS X?

Ora che so come modificare il link a cui puntano i link simbolici, sto cercando di capire come farlo in modo ricorsivo per qualsiasi link simbolico rotto. Sono un ragazzo PHP, quindi questa roba della CLI è alquanto strana per me ...

Sembra che ci siano alcuni elementi specifici a questo, vale a dire:

  1. Identifica un link simbolico rotto e recupera la sua posizione
  2. Ottieni la vecchia, ora non corretta, destinazione per il collegamento simbolico
  3. Costruisci il nuovo percorso corretto per il collegamento simbolico in modo che punti a
  4. Modifica il link simbolico

Il primo è abbastanza semplice:

find /path/to/search -type l | while read f; do if [ ! -e "$f" ]; then ls -l "$f"; fi; done

Questo mi dà una bella lista di tutti i link simbolici rotti trovati sotto la directory fornita. Ma credo che avrei bisogno di memorizzare la posizione di ciascuno in una variabile (array?) Per lavorare con esso.

Successivamente, sembra che cambiando l'azione fornita nella parte "allora" della logica, si otterrebbe la soluzione.

L'elemento 2 può essere recuperato usando:

readlink /path/to/broken/symlink

Quindi sembra che dobbiamo spingerlo in una variabile. Non sono chiaro su come farlo nel terminale.

Il numero 3 sarebbe una semplice modifica al percorso recuperato durante il passaggio 2. Devo sostituire il vecchio nome dell'unità, con il nuovo. Quindi cambia:

/Volumes/Old\ Drive/path/to/symlink

a

/Volumes/New\ Drive/path/to/symlink

Inoltre non è chiaro esattamente su come farlo all'interno di uno script CLI. Sembra che sia necessaria una sorta di sostituzione di stringhe. Qualcosa come str_replace nel mondo PHP.

Finalmente il passaggio 4 può essere fatto tramite:

ln -f -s /path/to/new/location/of/original /path/to/location/of/broken/symlink/

come dettagliato nella mia altra domanda, precedentemente collegata sopra.

In che modo racchiudere questi concetti insieme per ottenere il risultato desiderato di correggere tutti i miei collegamenti simbolici in un solo colpo?

    
posta Jonathan van Clute 08.12.2013 - 08:33
fonte

2 risposte

5

Dalla cima della mia testa (e senza alcun test):

  1. Crea un file di testo con il seguente contenuto

    #!/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
    
  2. Rendilo eseguibile eseguendo chmod +x name-of-file

  3. Esegui ./name-of-file /path/to/search

Questo è non testato , quindi prova prima con una directory di esempio.

Per aggiungere alcune spiegazioni

  • old_path=$(readlink "$symlink") esegue il comando in $(...) e assegna il risultato a $old_path
  • ${old_path/Old Drive/New Drive} sostituisce il testo in $old_path
risposta data 08.12.2013 - 11:12
fonte
5

In una shell bash , per impostare una variabile, usa semplicemente set NAME=bob o set VITAL_SIGNS=none .

Puoi anche impostare una variabile usando l'output di un comando chiamando la funzione bash -builtin read per assegnare l'output a una variabile denominata. Funziona bene in un flusso di pipe in questo modo:

ls -l | wc -l | read NUMBER_OF_LINES

Oppure puoi assegnare l'output direttamente a una variabile in questo modo:

LICENSE_KEY=$(cat ~/software/key.txt | grep KEY | awk '{print $1}')

Un ottimo modo per leggere le variabili in modo ricorsivo è in un loop come segue:

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

Tenendo presente quanto sopra, dovrebbe funzionare qualcosa come la seguente:

dimostra che una cartella non esiste

StuffeMac:dan stuffe$ ls ~/Desktop/broken_links
ls: /Users/stuffe/Desktop/broken_links: No such file or directory

dimostra che esiste una nuova cartella di destinazione

StuffeMac:dan stuffe$ ls ~/Desktop/working_links
StuffeMac:dan stuffe$

crea alcuni link non validi e validi

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

prendi un elenco di link morti in un file per l'input

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

esegui un ciclo su ogni link morto

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$

controlla i link simbolici dopo le modifiche

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
    
risposta data 08.12.2013 - 11:16
fonte

Leggi altre domande sui tag