GNU/Linux >> Linux Esercitazione >  >> Linux

`os.symlink` contro `ln -s`

os.symlink crea un singolo collegamento simbolico.

ln -s crea più collegamenti simbolici (se il suo ultimo argomento è una directory e c'è più di una fonte). L'equivalente di Python è qualcosa del tipo:

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

Quindi, come funziona quando fai ln -s /home/guest/dir1/* /home/guest/dir2/ ? Il tuo guscio lo fa funzionare, trasformando il carattere jolly in più argomenti. Se dovessi solo exec il ln comando con un carattere jolly, cercherà un'unica fonte chiamata letteralmente * in /home/guest/dir1/ , non tutti i file in quella directory.

L'equivalente di Python è qualcosa di simile (se non ti dispiace mescolare due livelli insieme e ignorare molti altri casi—tilde, variabili env, sostituzione di comandi, ecc. che sono possibili nella 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)))

Non puoi farlo con os.symlink da solo - nessuna delle due parti - perché non lo fa. È come dire "Voglio fare l'equivalente di find . -name foo utilizzando os.walk senza filtrare il nome." Oppure, del resto, voglio fare l'equivalente di ln -s /home/guest/dir1/* /home/guest/dir2/ senza che il guscio si gonfi per me."

La risposta giusta è usare glob o fnmatch o os.listdir più una regex, o quello che preferisci.

No usa os.walk , perché questo fa un ricorsivo filesystem walk, quindi non è nemmeno vicino alla shell * espansione.


* è un modello di estensione della shell, che nel tuo caso designa "tutti i file che iniziano con /home/guest/dir1/ ".

Ma è ruolo della tua shell espandere questo schema ai file che corrisponde. Non il ln comando.

Ma os.symlink non è una shell, è una chiamata del sistema operativo, quindi non supporta i modelli di estensione della shell. Dovrai fare quel lavoro nella tua sceneggiatura.

Per farlo, puoi usare os.walk o os.listdir . Come indicato nell'altra risposta, la chiamata appropriata dipenderà da cosa vuoi fare. (os.walk non sarebbe l'equivalente di * )

Per convincerti:esegui questo comando su una macchina Unix nel tuo terminale:python -c "import sys; print sys.argv" * . Vedrai che è la shell che sta facendo la corrispondenza.


Linux
  1. Personalizzazione della shell Bash

  2. Timeout in uno script di shell?

  3. Su quale shell sto correndo?

  4. Array associativi negli script della shell?

  5. Converti .txt in .csv nella shell

Shell dei comandi

Che cos'è Login Shell in Linux?

Tutorial passo passo sullo scripting della shell

Array negli script di shell

8 tipi di shell Linux

Cos'è un file .sh?