问题描述
我有一个工作正常的 bash 脚本,它创建和/或将当前的符号链接重写为新路径,而没有任何数据争用。如果程序尝试查找路径,则它将从符号链接获取旧路径或新路径。这是由于 -f模式而起作用的。这是 bash 的外观:
cd /srv/
ln -nsf /home/myproject/video123.ts latest_video.mkv
ln -nsf /home/myproject/video124.ts latest_video.mkv
ln -nsf /home/myproject/video125.ts latest_video.mkv
在python3中,有一个名为 os.symlink()的模块,该模块创建符号链接,但无法实现替代行为。
import os,errno
def symlink_force(target,link_name):
try:
os.symlink(target,link_name)
except OSError,e:
if e.errno == errno.EEXIST:
os.remove(link_name)
os.symlink(target,link_name)
else:
raise e
您可以看到,在很短的时间内会有停机时间,调用 os.remove(link_name)方法。关于如何在不删除现有符号链接的情况下进行覆盖的想法?
任何帮助表示赞赏。
解决方法
查看ln -nsf(带有strace)的行为将显示该命令由2个系统调用执行:
- 在目标文件夹中使用临时文件名在源文件中创建符号链接。
- 将临时文件重命名为目标文件
此方法(相对于remove / symlink)的优点在于,重命名可确保在任何时间目标文件都指向旧文件或新文件。
可能的Python实现(假设可以安全地使用“ .new”作为临时链接)
def symlink_force(target,link_name):
try:
temp_link = link_name + ".new"
os.remove(temp_link)
os.symlink(target,temp_link)
os.rename(temp_link,link_name)
except OSError e:
# Handle critical errors