Ho uno script Python che deve essere eseguito con una particolare installazione di Python. C'è un modo per fabbricare un shebang in modo che corra $FOO/bar/MyCustomPython
?
Ho uno script Python che deve essere eseguito con una particolare installazione di Python. C'è un modo per fabbricare un shebang in modo che corra $FOO/bar/MyCustomPython
?
Risposte:
La linea Shebang è molto limitata. In molte varianti unix (incluso Linux), puoi avere solo due parole: un comando e un singolo argomento. C'è anche spesso una limitazione di lunghezza.
La soluzione generale è scrivere un piccolo involucro di shell. Assegna un nome allo script Python foo.py
, avvicina lo script shell foo.py
e chiamalo foo
. Questo approccio non richiede alcuna intestazione particolare sullo script Python.
#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"
Un altro approccio allettante è scrivere uno script wrapper come quello sopra e metterlo #!/path/to/wrapper/script
come linea shebang nello script Python. Tuttavia, molti unice non supportano il concatenamento di script shebang, quindi non funzionerà.
Se MyCustomPython
fosse nel $PATH
, puoi usare env
per cercarlo:
#!/usr/bin/env MyCustomPython
import …
Ancora un altro approccio è quello di disporre che lo script sia sia uno script shell valido (che carica il giusto interprete Python su se stesso) sia uno script valido nella lingua di destinazione (qui Python). Ciò richiede che tu trovi un modo per scrivere uno script in doppia lingua per la tua lingua di destinazione. In Perl, questo è noto come if $running_under_some_shell
.
#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
if $running_under_some_shell;
use …
Ecco un modo per ottenere lo stesso effetto in Python. Nella shell, "true"
è l' true
utilità, che ignora i suoi argomenti (due stringhe a carattere singolo :
e '
) e restituisce un valore vero. In Python, "true"
è una stringa che è vera quando interpretata come booleana, quindi questa è if
un'istruzione che è sempre vera ed esegue una stringa letterale.
#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import …
Il codice Rosetta ha tali script in doppia lingua in diverse altre lingue.
PYTHONPATH
variabile env per caricare i moduli da una posizione non standard per uno script CGI su un sistema a cui non avevo accesso root. Salvavita. Grazie ancora.
Le linee Shebang non subiscono espansione variabile, quindi non puoi usarle in $FOO/MyCustomPython
quanto cercherebbero un eseguibile chiamato dollar-FOO -...
Un'alternativa è che il tuo shebang punti a uno script di shell come interprete, e questo script di shell può quindi utilizzare le variabili di ambiente per individuare quella corretta ed eseguirla.
Esempio: crea uno mypython.sh
script in /usr/local/bin
(o qualsiasi altra directory sul tuo $PATH
), con il seguente contenuto:
#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"
allora puoi usare questa riga di shebang per far eseguire uno script Python MyCustomPython
tramite mypython.sh
:
#!/usr/bin/env mypython.sh
$python
, non $PYTHON
- per convenzione, capitalizziamo le variabili di ambiente (PAGER, EDITOR, SHELL ... $PYTHON
nel tuo script non è una variabile di ambiente) e le variabili di shell interne (BASH_VERSION, RANDOM, ...). Tutti gli altri nomi di variabili devono contenere almeno una lettera minuscola. Questa convenzione evita di ignorare accidentalmente le variabili ambientali e interne. Inoltre, non utilizzare estensioni per i tuoi script. Gli script definiscono nuovi comandi che è possibile eseguire e ai comandi in genere non vengono assegnate estensioni.
Puoi usare il percorso assoluto per l'installazione personalizzata di Python, oppure puoi inserirlo nel tuo $PATH
e usare #!/usr/bin/env [command]
. In caso contrario, scrivere un wrapper per esso e utilizzare exec
per sostituire l'immagine di processo, come esempio:
#!/bin/bash
exec "$ENV/python" "$@"
Innanzitutto, determina in che modo la tua versione di Python è diversa dallo standard Python già installato (ad esempio un modulo aggiuntivo) e quindi all'inizio del programma 'cambia' come viene chiamato Python:
#!/usr/bin/python
import os
import sys
try:
import MyCustomModule
except ImportError:
# only need to use expandvar if you know the string below has an envvar
custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
os.execv(custprog, sys.argv) # call alternate python with the same arguments
raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter
Ciò dovrebbe consentire al programma di essere chiamato da qualsiasi altra istanza di Python. Faccio qualcosa di simile per un'istanza con libreria sql integrata che non può essere importata come modulo nel pitone del sistema.
Se è possibile sostituire $FOO
in $FOO/bar/MyCustomPython
con opzioni percorso concreto, si può dire la env
shebang dove andare a cercare la vostra versione personalizzata di Python impostando direttamente una consuetudine PATH
in esso.
#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python
Modifica : sembra funzionare solo senza virgolette attorno all'assegnazione del valore PATH:
#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python
PATH
così:PATH=$PATH:/path/to/whatever...