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

Я действительно хочу запустить эту команду …

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

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

Вероятно, вы захотите использовать команду find с maxdepth опции 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 

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

От человека ln :

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

Вместо этого вам нужно использовать цикл for.

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 \; 

./*/ и играя с помощью команды find, я обнаружил, что проще всего перебирать вещи, используя ./*/ . Спасибо за помощь! Я сделал сценарий в моей учетной записи github, который намного более точно настроен. Хотя это gitlab specific, потребуется всего несколько минут, чтобы изменить его на все, что вам нужно 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