Bash script to safely create symlinks?
Asked Answered
C

2

10

I'm trying to store all my profile configuration files (~/.xxx) in git. I'm pretty horrible at bash scripting but I imagine this will be pretty straight forward for you scripting gurus.

Basically, I'd like a script that will create symbolic links in my home directory to files in my repo. Twist is, I'd like it warn and prompt for overwrite if the symlink will be overwriting an actual file. It should also prompt if a sym link is going to be overwritten, but the target path is different.

I don't mind manually editing the script for each link I want to create. I'm more concerned with being able to quickly deploy new config scripts by running this script stored in my repo.

Any ideas?

Checkerwork answered 8/8, 2010 at 15:52 Comment(0)
T
15

The ln command is already conservative about erasing, so maybe the KISS approach is good enough for you:

ln -s git-stuff/home/.[!.]* .

If a file or link already exists, you'll get an error message and this link will be skipped.

If you want the files to have a different name in your repository, pass the -n option to ln so that it doesn't accidentally create a symlink in an existing subdirectory of that name:

ln -sn git-stuff/home/profile .profile
...

If you also want to have links in subdirectories of your home directory, cp -as reproduces the directory structure but creates symbolic links for regular files. With the -i option, it prompts if a target already exists.

cp -i -as git-stuff/home/.[!.]* .

(My answer assumes GNU ln and GNU cp, such as you'd find on Linux (and Cygwin) but usually not on other unices.)

Thomson answered 8/8, 2010 at 16:11 Comment(0)
R
1

The following has race conditions, but it is probably as safe as you can get without filesystem transactions:

# create a symlink at $dest pointing to $source
# not well tested
set -e   # abort on errors
if [[ ( -h $dest && $(readlink -n "$dest") != $source ) || -f $dest || -d $dest ]]
then
    read -p "Overwrite $dest? " answer
else
    answer=y
fi
[[ $answer == y ]] && ln -s -n -f -v -- "$source" "$dest"
Renatorenaud answered 8/8, 2010 at 16:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.