os.symlink
vytvoří jeden symbolický odkaz.
ln -s
vytvoří více symbolických odkazů (pokud je jeho posledním argumentem adresář a existuje více než jeden zdroj). Ekvivalent Pythonu je něco jako:
dst = args[-1]
for src in args[:-1]:
os.symlink(src, os.path.join(dst, os.path.dirname(src)))
Jak to tedy funguje, když uděláte ln -s /home/guest/dir1/* /home/guest/dir2/
? Váš shell to funguje tím, že zástupný znak převede na více argumentů. Pokud byste měli jen exec
ln
příkaz se zástupným znakem by hledal jediný zdroj doslova nazvaný *
v /home/guest/dir1/
, ne všechny soubory v tomto adresáři.
Ekvivalent Pythonu je něco jako (pokud vám nevadí smíchat dvě úrovně dohromady a ignorovat spoustu dalších případů – vlnovky, proměnné env, substituce příkazů atd., které jsou možné v shellu):
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)))
S os.symlink
to nemůžete udělat sám – kterákoli jeho část – protože to nedělá. Je to jako říct „Chci udělat ekvivalent find . -name foo
pomocí os.walk
bez filtrování podle názvu." Nebo, když na to přijde, chci udělat ekvivalent ln -s /home/guest/dir1/* /home/guest/dir2/
aniž by se pro mě skořápka kulila."
Správná odpověď je použít glob
nebo fnmatch
nebo os.listdir
plus regulární výraz nebo cokoliv jiného.
Ne použijte os.walk
, protože to dělá rekurzivní filesystem walk, takže to není ani blízko shellu *
rozšíření.
*
je vzor rozšíření shellu, který ve vašem případě označuje "všechny soubory začínající /home/guest/dir1/
".
Ale je to vaše role shellu, aby tento vzorec rozšířila k souborům, které se shodují. Ne ln
příkazu.
Ale os.symlink
není shell, je to volání OS – proto nepodporuje vzory rozšíření shellu. Tuto práci budete muset udělat ve svém skriptu.
K tomu můžete použít os.walk
nebo os.listdir
. Jak je uvedeno v druhé odpovědi, vhodný hovor bude záviset na tom, co chcete udělat. (os.walk
by nebylo ekvivalentem *
)
Abyste se přesvědčili:spusťte tento příkaz na Unixovém stroji ve svém terminálu:python -c "import sys; print sys.argv" *
. Uvidíte, že je to shell, který provádí párování.