GNU/Linux >> Znalost Linux >  >> Linux

`os.symlink` vs `ln -s`

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í.


Linux
  1. Na jakém Shellu běžím?

  2. Asociativní pole ve skriptech Shell?

  3. Zkažená historie?

  1. Přizpůsobení prostředí Bash

  2. Časový limit ve skriptu Shell?

  3. V shellu převeďte .txt na .csv

  1. Správné zamykání skriptů Shell?

  2. Pole v Unix Bourne Shell?

  3. Jak změnit Shell v Linuxu