Konwertuj dowiązania symboliczne na twarde

25

Chciałbym rekurencyjnie konwertować miękkie linki na twarde linki w katalogu. Próbowałem czegoś takiego:

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

… Ale ma dwa główne problemy:

  • nie rekurencyjne
  • pobiera pliki, które nie są dowiązaniami symbolicznymi

Byłoby miło jakoś nakarmić powyższą linię find -type l, ale nie jestem pewien, jak to zrobić.

Attila O.
źródło
1
Zobacz także [ta dyskusja] [1] ( cp -aH). [1]: unix.stackexchange.com/questions/94185/...
Michael Shigorin

Odpowiedzi:

34

To polecenie powinno działać:

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

Jak to działa:

  • find -type l znajdzie wszystkie linki w bieżącym katalogu.

  • -exec bash -c '...' {} \;wywołuje bash, aby wykonać ....

    Przekazuje {}- nazwę aktualnie przetwarzanego łącza - jako argument, do którego bash może uzyskać dostęp jako $0.

  • readlink -m "$0" zwraca bezwzględną ścieżkę miejsca docelowego dowiązania symbolicznego.

  • ln -f "$(readlink -m "$0")" "$0"overwrites ( -f) dowiązanie symboliczne $0twardym dowiązaniem do celu.

Jeśli z jakiegoś powodu nie można przekonwertować łącza, pozostanie ono nietknięte, a ln wydrukuje komunikat o błędzie.

Dennis
źródło
Czy w odniesieniu do tego ostatniego akapitu nie wystarczy podać bezwzględne ścieżki do bashi ln?
Daniel Beck
2
Mój problem polegał na tym, że readlink domyślnie zwraca ścieżkę względną, ale -eprzełącznik to naprawia.
Dennis
Jakie byłoby polecenie dla OSX?
Igor Markelov
@IgorMarkelov Przykro mi, ale nie mam pojęcia, czy chodzi o OSX.
Dennis
1
Na komputerze Mac jest to: brew install coreutilsi find * -type l -exec bash -c 'ln -f "$(greadlink -m "$0")" "$0"' {} \;.
Igor Markelov