2013-07-03 12 views
14

sto cercando di capire una delle risposte a questa domanda:Perché questo frammento con uno shebang #!/Bin/sh ed exec python all'interno di 4 virgolette singole funziona?

Cannot pass an argument to python with "#!/usr/bin/env python"

#!/bin/sh 
''''exec python -u -- "$0" ${1+"[email protected]"} # ''' 

Questo funziona bene, ma non capisco perché funziona con quattro zecche all'inizio di quella linea piuttosto di tre.

Inoltre, perché l'hash vicino alla fine di quella stringa?

+0

Basta notare che questo lancerà * qualsiasi * pitone in '$ path' quindi è ** terribilmente insicura ** rispetto al' #/usr/bin/env -i! python' * o * (ancora meglio) conoscendo e utilizzando il percorso completo: '#!/usr/bin/python'. –

risposta

25

Python supporta stringhe triple-citato:

'''something''' 

Shell supporta solo le stringhe racchiuse tra virgolette singole:

'something' 

Utilizzando quattro citazioni, sh vede che come 2 stringhe vuote, ma Python vede i primi tre come l'inizio di una stringa con quotatura tripla e include il quarto come parte del valore stringa.

Il resto della riga viene quindi interpretato come un comando da sh, ma come parte di una stringa da Python.

Il # quindi forma un commento per quanto riguarda sh è interessato, ma è ancora una stringa per Python, chiudendolo con una tripla virgola di chiusura.

Quindi, per riassumere:

  • sh vede: stringa vuota ('')-stringa vuota ('')-comando (exec python -u -- "$0" ${1+"[email protected]"})-commento (# ''')
  • Python vede: letterale stringa con quotatura tripla (contenente i caratteri 'exec python -u -- "$0" ${1+"[email protected]"} #)

Così sh esegue quel comando, si sostituisce con la python -u -- con il nome dello script e il resto degli argomenti della riga di comando, e Python legge questo file e appena vede una stringa iniziale letterale che non sta da nessuna parte.

Poiché è la prima stringa letterale nel file, verrà impostata come docstring per il modulo __main__ ma non importa se questo è lo script principale.

+0

cos'è '$ {1 +" $ @ "}'? com'è diverso da '$ @'? – Dog

+0

@Dog: Ciò significa che: * se * param 1 è impostato, sostituire '" $ @ "' (parametri quotati) altrimenti sostituisce null. –

+0

Puoi modificare la docstring dopo il fatto, mi chiedo? – Will

0

mi basta usare:

#!/bin/sh 
''':' 
exec python -tt "$0" "[email protected]" 
''' 
# The above shell shabang trick is more portable than /usr/bin/env and supports adding arguments to the interpreter (python -tt) 
+0

Qual è il vantaggio dell'utilizzo della soluzione rispetto alla risposta accettata? – akhan

+0

Questo non risponde alla domanda postata, non importa cosa * tu * usi, l'OP vuole capire come funziona un pezzo di codice specifico. –

Problemi correlati