安全创建符号链接的Bash脚本?

10
我想将我所有的配置文件(~/.xxx)存储在Git中。我很糟糕的bash脚本编写能力,但我认为这对于你这些脚本大师来说应该很简单。
基本上,我想要一个脚本,在我的主目录中创建符号链接到仓库中的文件。重点是,如果符号链接将要覆盖实际文件,它应该发出警告和提示是否覆盖。如果符号链接将被覆盖,但目标路径不同,也应该发出提示。
我不介意手动编辑每个要创建的链接的脚本。我更关心的是通过运行存储在我的仓库中的此脚本能够快速部署新的配置脚本。
有任何想法吗?
2个回答

15
< p > < code > ln 命令已经很谨慎地处理了擦除,所以也许 KISS 方法已经足够适合你了:

ln -s git-stuff/home/.[!.]* .
如果文件或链接已经存在,你将会收到一个错误消息并且该链接将被跳过。
如果你想让在你的仓库里的文件有一个不同的名字,可以给 ln 命令传递 -n 选项,这样它就不会意外地创建一个指向已存在子目录的符号链接:
ln -sn git-stuff/home/profile .profile
...

如果你想在你的主目录下的子目录中也有链接,cp -as可以重现目录结构,但对于普通文件则创建符号链接。使用-i选项时,它会在目标已经存在时提示。

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

(我的回答假设使用GNU ln和GNU cp,例如您在Linux(和Cygwin)上找到的那样,但通常不适用于其他Unix系统。)


1

以下代码存在竞态条件,但是在没有文件系统事务的情况下,这可能是最安全的方式:

# 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"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接