Creating symbolic link recursively
Solution 1
You'll probably want to use the find
command using the maxdepth
option. I created this sample directory structure:
/tmp/parent
/tmp/parent/subdir2
/tmp/parent/subdir1
/tmp/parent/subdir4
/tmp/parent/subdir4/notme
/tmp/parent/subdir3
Let's say I wanted to create a symlink to /tmp/hooks
in each subdir but not the notme
subdir:
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
Solution 2
find
can be used to execute a command in the context of every directory under a specific path.
The following command looks for all files under /var/opt/gitlab/git-data/repositories/web/
that are directories (-type d
) and creates a symbolic link relative to the current directory it is examining (represented by {}
in -exec
)
So the following find
command will do what you require:
find /var/opt/gitlab/git-data/repositories/web/ -type d -exec ln /opt/gitlab/embedded/service/gitlab-shell/hooks/ {}/hooks \;
Solution 3
After looking around and playing with the find command I found it was easier to just loop over things using ./*/
. Thanks for all the help! I made a script on my github account that is much more finely tuned. Although it is gitlab specific It would only take a few minutes to modify it for whatever you need 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
Solution 4
ln
works a bit like cp
. If there are more than two arguments, the last one is treated as a directory.
From man ln:
ln [option]... target... directory
You'll need to use a for loop instead.
Related videos on Youtube
![eatingthenight](https://i.stack.imgur.com/Era78.png?s=256&g=1)
eatingthenight
Updated on September 18, 2022Comments
-
eatingthenight almost 2 years
I essentially want to run this command...
ln -s /opt/gitlab/embedded/service/gitlab-shell/hooks/ /var/opt/gitlab/git-data/repositories/web/*/hooks
This would create a symbolic link in all folders under the web folder called hooks however it returns no errors but it does not actually add the symlink.