Создание символической ссылки рекурсивно

Создание символической ссылки рекурсивно

По сути, я хочу выполнить эту команду...

ln -s /opt/gitlab/embedded/service/gitlab-shell/hooks/ /var/opt/gitlab/git-data/repositories/web/*/hooks

Это создаст символическую ссылку во всех папках внутри веб-папки с именем hooks, однако это не вернет никаких ошибок, но фактически не добавит символическую ссылку.

решение1

Вероятно, вы захотите использовать findкоманду с maxdepthопцией. Я создал этот пример структуры каталогов:

/tmp/parent
/tmp/parent/subdir2
/tmp/parent/subdir1
/tmp/parent/subdir4
/tmp/parent/subdir4/notme
/tmp/parent/subdir3

Допустим, я хочу создать символическую ссылку /tmp/hooksв каждом подкаталоге, но не в notmeсамом подкаталоге:

root@xxxxxxvlp12 ~ $ find /tmp/parent -type d -maxdepth 1 -exec ln -s /tmp/hooks {} \;
root@xxxxxxvlp12 ~ $ find /tmp/parent -ls
2490378    4 drwxr-xr-x   6 root     root         4096 Oct  7 12:39 /tmp/parent
2490382    4 drwxr-xr-x   2 root     root         4096 Oct  7 12:39 /tmp/parent/subdir2
2490394    0 lrwxrwxrwx   1 root     root           10 Oct  7 12:39 /tmp/parent/subdir2/hooks -> /tmp/hooks
2490379    4 drwxr-xr-x   2 root     root         4096 Oct  7 12:39 /tmp/parent/subdir1
2490395    0 lrwxrwxrwx   1 root     root           10 Oct  7 12:39 /tmp/parent/subdir1/hooks -> /tmp/hooks
2490389    4 drwxr-xr-x   3 root     root         4096 Oct  7 12:39 /tmp/parent/subdir4
2490390    4 drwxr-xr-x   2 root     root         4096 Oct  7 12:38 /tmp/parent/subdir4/notme
2490396    0 lrwxrwxrwx   1 root     root           10 Oct  7 12:39 /tmp/parent/subdir4/hooks -> /tmp/hooks
2490387    4 drwxr-xr-x   2 root     root         4096 Oct  7 12:39 /tmp/parent/subdir3
2490397    0 lrwxrwxrwx   1 root     root           10 Oct  7 12:39 /tmp/parent/subdir3/hooks -> /tmp/hooks
2490391    0 lrwxrwxrwx   1 root     root           10 Oct  7 12:39 /tmp/parent/hooks -> /tmp/hooks

решение2

findможет использоваться для выполнения команды в контексте каждого каталога по определенному пути.

Следующая команда ищет все файлы, находящиеся в /var/opt/gitlab/git-data/repositories/web/каталогах ( -type d), и создает символическую ссылку относительно текущего проверяемого каталога (представленного в {}) -exec.

Итак, следующая findкоманда сделает то, что вам нужно:

find /var/opt/gitlab/git-data/repositories/web/ -type d -exec ln /opt/gitlab/embedded/service/gitlab-shell/hooks/ {}/hooks \;

решение3

lnработает немного похоже на cp. Если аргументов больше двух, последний рассматривается как каталог.

Отчеловек в:

ln [option]... target... directory

Вместо этого вам придется использовать цикл for.

решение4

Посмотрев вокруг и поигравшись с командой find, я обнаружил, что проще просто перебирать все с помощью ./*/. Спасибо за помощь! Я сделал скрипт на своем аккаунте github, который настроен гораздо более тонко. Хотя он специфичен для gitlab, его изменение под любые нужды займет всего несколько минутhttps://github.com/michaeljs1990/bash-scripts/blob/master/gitlab-hooks-migration.sh.

#!/bin/bash

find . -name "hooks" -type l -delete

hooks="hooks"
for i in ./*/; do
    ln -s  /opt/gitlab/embedded/service/gitlab-shell/hooks/ $i$hooks
done

Связанный контент