bash “安全地”替换重要的符号链接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1385244/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Replace important symbolic link ‘safely’
提问by Micha? Górny
I would like to change the target of symbolic link from within a bash script. The problem is that the symlink is quite important (it's /bin/sh, namely) and I would to do it in fashion that:
我想从 bash 脚本中更改符号链接的目标。问题是符号链接非常重要(它是/bin/sh,即),我会以时尚的方式做到这一点:
- New target will be available immediately after removing old, i.e. there will be no possibility that something will notice disappearing of it,
- There will be no possibility that the change will fail in the middle, i.e. leaving user with symlink removed and no new one.
- 删除旧目标后,新目标将立即可用,即不可能有东西注意到它消失,
- 更改不会在中间失败,即让用户删除符号链接并且没有新的符号链接。
I thought about two methods. Either using plain ln:
我想到了两种方法。要么使用普通ln:
ln -fs /bin/bash /bin/sh
or using mv:
或使用mv:
ln -s /bin/bash /bin/sh.new
mv /bin/sh.new /bin/sh
Which one will suit my needs better? Is there any possibility that one of them would try to replace the symlink target instead of symlink itself?
哪一个更适合我的需求?其中一个是否有可能尝试替换符号链接目标而不是符号链接本身?
回答by ire_and_curses
Renaming (mv) is an atomic operation; creating a new symlink is not (delete old symlink; create new one). So you should use mv:
重命名 ( mv) 是原子操作;创建新的符号链接不是(删除旧的符号链接;创建新的符号链接)。所以你应该使用mv:
$ ln -s new current_tmp && mv -Tf current_tmp current
Here's a blog postdiscussing this. Also, if you're worried about what will happen, why not try it on a non-critical symlink first?
回答by Greg Hewgill
It looks like (from the man page) ln -funlinks the symlink before making the new one, which means mvis the better option for this.
看起来(来自手册页)ln -f在创建新符号链接之前取消链接符号链接,这意味着这mv是更好的选择。
I would, however, strongly recommend againstlinking /bin/shto bash. Many scripts use:
但是,我强烈建议不要链接/bin/sh到bash. 许多脚本使用:
#!/bin/sh
and are written assuming that the shell is the classic Bourne shell. If this were to run bashinstead, you could easily get obscure incompatibilities between what the script assumes shdoes and what bashactuallydoes. These will be nearly impossible to track down.
并且假设 shell 是经典的 Bourne shell。如果改为运行它bash,您很容易在脚本假定的内容sh和bash实际执行的内容之间产生模糊的不兼容性。这些几乎不可能被追踪到。

