Перетворити посилання на жорсткі посилання


25

Я хотів би рекурсивно перетворювати м'які посилання в жорсткі посилання в каталозі. Я спробував щось подібне:

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

... але це дві основні проблеми:

  • не рекурсивний
  • збирає файли, що не є символічними посиланнями

Було б добре якось подати вищезазначений рядок find -type l, але я не впевнений, як це зробити.


1
Дивіться також [це обговорення] [1] ( cp -aH). [1]: unix.stackexchange.com/questions/94185/…
Михайло

Відповіді:


34

Ця команда повинна працювати:

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

Як це працює:

  • find -type l знаходить усі посилання в поточному каталозі.

  • -exec bash -c '...' {} \;викликає bash для виконання ....

    Це передається {}- ім'я посилання, яке зараз обробляється - як аргумент, до якого bash може отримати доступ $0.

  • readlink -m "$0" повертає абсолютний шлях призначення символічного посилання.

  • ln -f "$(readlink -m "$0")" "$0"перезаписує ( -f) символічне посилання $0жорстким посиланням на свою ціль.

Якщо посилання з якихось причин неможливо перетворити, воно залишиться недоторканим і ln надрукує повідомлення про помилку.


Щодо останнього абзацу, чи не достатньо буде вказати абсолютні шляхи до bashта ln?
Даніель Бек

2
Моя проблема полягала в тому, що readlink повертає відносний шлях за замовчуванням, але -eкомутатор це виправляє.
Денніс

Що було б командою для OSX?
Ігор Маркелов

@IgorMarkelov Вибачте, але в мене немає поняття, коли мова йде про OSX.
Денніс

1
На Mac це: brew install coreutilsі find * -type l -exec bash -c 'ln -f "$(greadlink -m "$0")" "$0"' {} \;.
Ігор Маркелов
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.