如何更改为符号链接以在Python中从一个文件指向另一个文件?os.symlink()函数似乎只能用于创建新的符号链接.
小智 27
如果您需要原子修改,则取消链接将不起作用.
更好的解决方案是创建一个新的临时符号链接,然后将其重命名为现有符号链接:
os.symlink(target, tmpLink)
os.rename(tmpLink, linkName)
Run Code Online (Sandbox Code Playgroud)
您可以检查以确保它也已正确更新:
if os.path.realpath(linkName) == target:
# Symlink was updated
Run Code Online (Sandbox Code Playgroud)
根据os.rename的文档,可能无法在Windows中自动更改符号链接.在这种情况下,您只需删除并重新创建.
Rob*_*mer 23
一个尝试符号链接的小函数,如果由于现有文件而失败,它会删除它并再次链接.
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
Run Code Online (Sandbox Code Playgroud)
鉴于overwrite=True,此函数将安全地用符号链接覆盖现有文件。
它认识到竞争条件,这就是为什么它不短,但它是安全的。
import os, tempfile
def symlink(target, link_name, overwrite=False):
'''
Create a symbolic link named link_name pointing to target.
If link_name exists then FileExistsError is raised, unless overwrite=True.
When trying to overwrite a directory, IsADirectoryError is raised.
'''
if not overwrite:
os.symlink(target, link_name)
return
# os.replace() may fail if files are on different filesystems
link_dir = os.path.dirname(link_name)
# Create link to target with temporary filename
while True:
temp_link_name = tempfile.mktemp(dir=link_dir)
# os.* functions mimic as closely as possible system functions
# The POSIX symlink() returns EEXIST if link_name already exists
# https://pubs.opengroup.org/onlinepubs/9699919799/functions/symlink.html
try:
os.symlink(target, temp_link_name)
break
except FileExistsError:
pass
# Replace link_name with temp_link_name
try:
# Pre-empt os.replace on a directory with a nicer message
if not os.path.islink(link_name) and os.path.isdir(link_name):
raise IsADirectoryError(f"Cannot symlink over existing directory: '{link_name}'")
os.replace(temp_link_name, link_name)
except:
if os.path.islink(temp_link_name):
os.remove(temp_link_name)
raise
Run Code Online (Sandbox Code Playgroud)
学徒注意事项:
如果该功能失败(例如计算机崩溃),则可能存在到目标的附加随机链接。
一个不太可能的竞争条件仍然存在:在随机命名的符号链接处创建的符号链接temp_link_name可以在替换之前被另一个进程修改link_name。
我提出了一个python 问题来强调os.symlink()要求目标不存在的问题,有人建议我在邮件列表中提出我的建议python-ideas
感谢罗伯特Siemer的输入。
我最近研究了这个问题,并发现,最好的办法确实是unlink,然后symlink.但是,如果您只需要修复损坏的链接,例如使用自动替换,那么您可以执行以下操作os.readlink:
for f in os.listdir(dir):
path = os.path.join(dir, f)
old_link = os.readlink(path)
new_link = old_link.replace(before, after)
os.unlink(path)
os.symlink(new_link, path)
Run Code Online (Sandbox Code Playgroud)