Converti i collegamenti simbolici in collegamenti reali


25

Vorrei convertire ricorsivamente i soft link in hard link in una directory. Ho provato qualcosa del genere:

for f in *; do (mv $f{,~} && ln $(readlink $f~) && rm $f~) done

... ma ha due problemi principali:

  • non ricorsivo
  • raccoglie file che non sono collegamenti simbolici

Sarebbe bello in qualche modo alimentare la riga sopra find -type l, ma non sono sicuro di come farlo.


1
Vedi anche [questa discussione] [1] ( cp -aH). [1]: unix.stackexchange.com/questions/94185/…
Michael Shigorin,

Risposte:


34

Questo comando dovrebbe funzionare:

find -type l -exec bash -c 'ln -f "$(readlink -m "$0")" "$0"' {} \;

Come funziona:

  • find -type l trova tutti i collegamenti nella directory corrente.

  • -exec bash -c '...' {} \;invoca bash per l'esecuzione ....

    Passa {}- il nome del collegamento attualmente in fase di elaborazione - come argomento, a cui bash può accedere come $0.

  • readlink -m "$0" restituisce il percorso assoluto della destinazione del collegamento simbolico.

  • ln -f "$(readlink -m "$0")" "$0"sovrascrive ( -f) il collegamento simbolico $0con un collegamento reale al suo obiettivo.

Se il collegamento non può essere convertito per qualche motivo, rimarrà intatto e verrà stampato un messaggio di errore.


Per quanto riguarda l'ultimo paragrafo, non sarebbe sufficiente specificare percorsi assoluti verso bashe ln?
Daniel Beck

2
Il mio problema era che readlink restituiva un percorso relativo per impostazione predefinita, ma l' -einterruttore lo risolve.
Dennis,

Quale sarebbe il comando per OSX?
Igor Markelov,

@IgorMarkelov Mi dispiace, ma non ho idea di quando si tratta di OSX.
Dennis,

1
Su un Mac è: brew install coreutilse find * -type l -exec bash -c 'ln -f "$(greadlink -m "$0")" "$0"' {} \;.
Igor Markelov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.