GNU/Linux >> LINUX-Kenntnisse >  >> Linux

`os.symlink` gegen `ln -s`

os.symlink erstellt einen einzelnen Symlink.

ln -s erstellt mehrere Symlinks (wenn sein letztes Argument ein Verzeichnis ist und es mehr als eine Quelle gibt). Das Python-Äquivalent sieht so aus:

dst = args[-1]
for src in args[:-1]:
    os.symlink(src, os.path.join(dst, os.path.dirname(src)))

Also, wie funktioniert es, wenn Sie ln -s /home/guest/dir1/* /home/guest/dir2/ machen ? Ihre Schale macht das möglich, indem der Platzhalter in mehrere Argumente umgewandelt wird. Wenn Sie nur exec müssten die ln mit einem Platzhalter, würde er nach einer einzigen Quelle mit dem wörtlichen Namen * suchen in /home/guest/dir1/ , nicht alle Dateien in diesem Verzeichnis.

Das Python-Äquivalent sieht so aus (wenn es Ihnen nichts ausmacht, zwei Ebenen zusammenzumischen und viele andere Fälle zu ignorieren – Tilden, Umgebungsvariablen, Befehlsersetzung usw., die auf der Shell möglich sind):

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)))

Mit os.symlink geht das nicht allein – irgendein Teil davon – weil es das nicht tut. Es ist, als würde man sagen:„Ich möchte das Äquivalent von find . -name foo machen mit os.walk ohne nach dem Namen zu filtern." Oder ich möchte das Äquivalent von ln -s /home/guest/dir1/* /home/guest/dir2/ machen ohne dass die Muschel für mich globbelt."

Die richtige Antwort ist die Verwendung von glob , oder fnmatch , oder os.listdir plus einen regulären Ausdruck oder was auch immer Sie bevorzugen.

nicht Verwenden Sie os.walk , denn das macht eine rekursive Filesystem Walk, also ist es nicht einmal in der Nähe von Shell * Erweiterung.


* ist ein Shell-Erweiterungsmuster, das in Ihrem Fall "alle Dateien bezeichnet, die mit /home/guest/dir1/ beginnen ".

Aber es ist die Rolle Ihrer Shell, dieses Muster zu erweitern zu den passenden Dateien. Nicht die ln Befehls.

Aber os.symlink ist keine Shell, sondern ein Betriebssystemaufruf - daher werden keine Shell-Erweiterungsmuster unterstützt. Sie müssen diese Arbeit in Ihrem Skript erledigen.

Dazu können Sie os.walk verwenden , oder os.listdir . Wie in der anderen Antwort angegeben, hängt der geeignete Anruf davon ab, was Sie tun möchten. (os.walk wäre nicht das Äquivalent von * )

Um sich selbst zu überzeugen:Führen Sie diesen Befehl auf einem Unix-Rechner in Ihrem Terminal aus:python -c "import sys; print sys.argv" * . Sie werden sehen, dass es die Shell ist, die den Abgleich durchführt.


Linux
  1. Anpassen der Bash-Shell

  2. Zeitüberschreitung in einem Shell-Skript?

  3. Auf welcher Shell laufe ich?

  4. Assoziative Arrays in Shell-Skripten?

  5. Richtiges Sperren in Shell-Skripten?

Kommando-Shell

Was ist die Login-Shell in Linux?

Shell-Scripting Schritt-für-Schritt-Tutorial

Arrays in Shell-Skripten

8 Arten von Linux-Shells

Was ist eine .sh-Datei?