os.symlink
membuat satu symlink.
ln -s
membuat banyak symlink (jika argumen terakhirnya adalah direktori, dan ada lebih dari satu sumber). Setara dengan Python adalah sesuatu seperti:
dst = args[-1]
for src in args[:-1]:
os.symlink(src, os.path.join(dst, os.path.dirname(src)))
Jadi, bagaimana cara kerjanya saat Anda melakukan ln -s /home/guest/dir1/* /home/guest/dir2/
? cangkang Anda membuatnya berfungsi, dengan mengubah wildcard menjadi beberapa argumen. Jika Anda hanya exec
ln
perintah dengan wildcard, itu akan mencari satu sumber yang secara harfiah bernama *
di /home/guest/dir1/
, tidak semua file di direktori itu.
Setara dengan Python adalah sesuatu seperti (jika Anda tidak keberatan menggabungkan dua level bersama-sama dan mengabaikan banyak kasus lain—tilde, variabel env, substitusi perintah, dll. yang dimungkinkan di shell):
dst = args[-1]
for srcglob in args[:-1]:
for src in glob.glob(srcglob):
os.symlink(src, os.path.join(dst, os.path.dirname(src)))
Anda tidak dapat melakukannya dengan os.symlink
sendirian—baik bagian dari itu—karena tidak melakukan itu. Ini seperti mengatakan "Saya ingin melakukan yang setara dengan find . -name foo
menggunakan os.walk
tanpa memfilter namanya." Atau, dalam hal ini, saya ingin melakukan yang setara dengan ln -s /home/guest/dir1/* /home/guest/dir2/
tanpa shell globbing untuk saya."
Jawaban yang tepat adalah menggunakan glob
, atau fnmatch
, atau os.listdir
plus regex, atau apa pun yang Anda suka.
Jangan jangan gunakan os.walk
, karena itu merupakan rekursif sistem file berjalan, jadi bahkan tidak dekat dengan shell *
ekspansi.
*
adalah pola ekstensi shell, yang dalam kasus Anda menunjuk "semua file dimulai dengan /home/guest/dir1/
".
Tapi itu peran shell Anda untuk memperluas pola ini ke file yang cocok. Bukan ln
perintah.
Tapi os.symlink
bukan shell, ini panggilan OS - karenanya, tidak mendukung pola ekstensi shell. Anda harus melakukannya dalam skrip Anda.
Untuk melakukannya, Anda dapat menggunakan os.walk
, atau os.listdir
. Seperti yang ditunjukkan pada jawaban lain, panggilan yang sesuai akan bergantung pada apa yang ingin Anda lakukan. (os.walk
tidak akan sama dengan *
)
Untuk meyakinkan diri sendiri:jalankan perintah ini pada mesin Unix di terminal Anda:python -c "import sys; print sys.argv" *
. Anda akan melihat bahwa shell yang melakukan pencocokan.