昨天用到了os.symlink函數(shù),在使用過(guò)程中踩了幾個(gè)坑,記錄下
注:下文所有的代碼都是針對(duì) Linux 等 POSIX 系統(tǒng),Windows系統(tǒng)沒(méi)有測(cè)試過(guò)
首先來(lái)看下os.symlink函數(shù)的介紹
Help on built-in function symlink in module posix:
symlink(...)
symlink(src, dst)
Create a symbolic link pointing to src named dst.
看介紹里完全沒(méi)有說(shuō) src和dst能不能用 relative path,也沒(méi)規(guī)定說(shuō)必須用absolute path
只能自己摸索了
- src和dst都是absolute path;完美,非常順利的建立了鏈接
- src是relative path,dst 是 absolute path;此處遇到了坑,后面詳細(xì)說(shuō)明
- src是absolute path, dst是relative path;此處也有坑,后敘
- src和dst都是relative path,也有坑
總之,凡是用到relative path的都需要注意
舉例說(shuō)明:
src:/tmp/make/CleanSpec.mk
dst: /tmp/code/build/CleanSpec.mk
當(dāng)前目錄:/tmp
情景1 src和dst都是absolute path
這種就不說(shuō)了吧,鐵定成功
情景2,src用relative path,dst用absolute path
os.symlink('make/CleanSpec.mk', '/tmp/code/build/CleanSpec.mk')
鏈接創(chuàng)建了,但沒(méi)有指向src,是個(gè)空的文件;原因是 dst是從它所在的目錄去選擇src的,而src配置的是'make/CleanSpec.mk',那么dst查找的src就是 '/tmp/code/build/make/CleanSpec.mk',根本沒(méi)有這個(gè)文件,當(dāng)然找不到
所以src必須是相對(duì)于dst的relative path,也就是 '../../make/CleanSpce.mk'
os.path.relpath('/tmp/make/CleanSpec.mk', start='/tmp/code/build/') # 可以用relpath方法獲取relative path,注意start是個(gè)目錄
os.symlink('../../make/CleanSpce.mk', '/tmp/code/build/CleanSpec.mk')
情景3,src用absolute path,dst用relative path
# 在當(dāng)前目錄下(/tmp)
os.symlink('/tmp/make/CleanSpec.mk', 'code/build/CleanSpec.mk')
可以正確地創(chuàng)建鏈接。但是當(dāng)我們把當(dāng)前目錄(/tmp)切換到/tmp/make,上面的命令就無(wú)法正確的創(chuàng)建鏈接了。因?yàn)閐st是從當(dāng)前目錄開始去尋找路徑的,上面的dst relative path,在把當(dāng)前目錄切換到/tmp/make之后,表示的路徑是/tmp/make/code/build/CleanSpec.mk,而/tmp/make/code/build目錄是不存在的,所以無(wú)法創(chuàng)建成功,要改成'../code/build/CleanSpec.mk'
所以dst必須是相對(duì)于當(dāng)前目錄的relative path。也可以用os.path.relpath函數(shù)獲得,只是start=當(dāng)前路徑
情景4,src和dst都是relative path
只要理解了情景2和情景3的結(jié)論,那情景4對(duì)你來(lái)說(shuō)就so easy~
只要記住src是相對(duì)于dst的relative path,dst是相對(duì)于當(dāng)前路徑的relative path,就能正確的創(chuàng)建鏈接。
# 當(dāng)前路徑(/tmp)
os.symlink('../../make/CleanSpec.mk', 'code/build/CleanSpec.mk')
# 當(dāng)前路徑(/tmp/make)
os.symlink('../../make/CleanSpec.mk', '../code/build/CleanSpec.mk')
總結(jié)
os.symlink 可以簡(jiǎn)單的理解為 等同于 Linux系統(tǒng)的 ln -s命令
它的兩個(gè)參數(shù)可以是relative path,也可以是absolute path
只是要記住:
- source 的 relative path是相對(duì)于 destination的
- destination的relative path是相對(duì)于 當(dāng)前路徑的
只要把握這兩點(diǎn),創(chuàng)建鏈接就不會(huì)踩坑
記于 2018-01-09