昨天用到了os.symlink函数,在使用过程中踩了几个坑,记录下
注:下文所有的代码都是针对 Linux 等 POSIX 系统,Windows系统没有测试过
首先来看下os.symlink函数的介绍
Help on built-in function symlink in module posix:
symlink(...)
symlink(src, dst)
Create a symbolic link pointing to src named dst.
看介绍里完全没有说 src和dst能不能用 relative path,也没规定说必须用absolute path
只能自己摸索了
- src和dst都是absolute path;完美,非常顺利的建立了链接
- src是relative path,dst 是 absolute path;此处遇到了坑,后面详细说明
- src是absolute path, dst是relative path;此处也有坑,后叙
- src和dst都是relative path,也有坑
总之,凡是用到relative path的都需要注意
举例说明:
src:/tmp/make/CleanSpec.mk
dst: /tmp/code/build/CleanSpec.mk
当前目录:/tmp
情景1 src和dst都是absolute path
这种就不说了吧,铁定成功
情景2,src用relative path,dst用absolute path
os.symlink('make/CleanSpec.mk', '/tmp/code/build/CleanSpec.mk')
链接创建了,但没有指向src,是个空的文件;原因是 dst是从它所在的目录去选择src的,而src配置的是'make/CleanSpec.mk',那么dst查找的src就是 '/tmp/code/build/make/CleanSpec.mk',根本没有这个文件,当然找不到
所以src必须是相对于dst的relative path,也就是 '../../make/CleanSpce.mk'
os.path.relpath('/tmp/make/CleanSpec.mk', start='/tmp/code/build/') # 可以用relpath方法获取relative path,注意start是个目录
os.symlink('../../make/CleanSpce.mk', '/tmp/code/build/CleanSpec.mk')
情景3,src用absolute path,dst用relative path
# 在当前目录下(/tmp)
os.symlink('/tmp/make/CleanSpec.mk', 'code/build/CleanSpec.mk')
可以正确地创建链接。但是当我们把当前目录(/tmp)切换到/tmp/make,上面的命令就无法正确的创建链接了。因为dst是从当前目录开始去寻找路径的,上面的dst relative path,在把当前目录切换到/tmp/make之后,表示的路径是/tmp/make/code/build/CleanSpec.mk,而/tmp/make/code/build目录是不存在的,所以无法创建成功,要改成'../code/build/CleanSpec.mk'
所以dst必须是相对于当前目录的relative path。也可以用os.path.relpath函数获得,只是start=当前路径
情景4,src和dst都是relative path
只要理解了情景2和情景3的结论,那情景4对你来说就so easy~
只要记住src是相对于dst的relative path,dst是相对于当前路径的relative path,就能正确的创建链接。
# 当前路径(/tmp)
os.symlink('../../make/CleanSpec.mk', 'code/build/CleanSpec.mk')
# 当前路径(/tmp/make)
os.symlink('../../make/CleanSpec.mk', '../code/build/CleanSpec.mk')
总结
os.symlink 可以简单的理解为 等同于 Linux系统的 ln -s
命令
它的两个参数可以是relative path,也可以是absolute path
只是要记住:
- source 的 relative path是相对于 destination的
- destination的relative path是相对于 当前路径的
只要把握这两点,创建链接就不会踩坑
记于 2018-01-09
网友评论