Como posso usar o shebang para diferenciar as versões do python?

2

Temos várias versões diferentes do python que module load . Estes podem ser um vanilla python 2 ou 3 instalar, ou uma versão anaconda com toda uma carga de bibliotecas extras.

No momento, se eu escrever um script que requer que eu use uma instalação específica de python (que eu encontro usando module load python/ana ; which python ), eu tenho que #! para um caminho explícito. Por exemplo

#!/path/to/anaconda/1.7.0/64/bin/python

aponta para a versão atual do python que é carregada quando eu faço module load python/anaconda no momento.

Este módulo não é gerenciado por mim, portanto, se alguém atualizar o módulo para usar /path/to/anaconda/1.7.1/64/bin/python e excluir o 1.7.0, meu script parará de funcionar.

Existe uma maneira padrão para um script especificar tanto o interpretador a ser usado como o módulo do qual o interpretador deve ser carregado? Algo como

#!/blah/module_env python/anaconda python -c

Como alternativa, existem outras opções que não precisam de acesso root? Nossas máquinas Linux corporativas estão bloqueadas para que não possamos instalar nosso próprio software ou alterar a configuração /use/bin/env , apenas o software module load que foi disponibilizado.

    
por Mark Booth 27.07.2017 / 16:47

1 resposta

2

Eu não estou familiarizado com esse module de seu software, mas parece que você deve ser capaz de fazer algo como:

#! /bin/sh -
'eval' '. "$MODULES_HOME/init/sh"; module load something || exit; exec python -- "$0" "$@"'

python script follows

Isso será interpretado pela primeira vez por sh , que então chamará module e executará python no mesmo script e com os mesmos argumentos.

As duas primeiras linhas serão ignoradas por python , a primeira porque é um comentário, a segunda porque é apenas a concatenação de duas sequências.

Mais geralmente:

#! /bin/sh -
'eval' 'single-line-of-shell-code-with-no-single-quote; exec python -- "$0" "$@"'

É uma maneira genérica de ter um script executável python em que algum código de shell de preâmbulo é executado antecipadamente. Para o código de shell de várias linhas, você também pode usar as python quotes de '''...''' :

#! /bin/sh -
':' '''python script with shell preamble'

arbitrary shell code here provided it doesn't contain
a sequence of 3 single quotes.

exec python -- "$0" "$@"
'''

print("Hello World")

Então, aqui:

#! /bin/sh -
':' '''python script with shell preamble'
"$MODULES_HOME/init/sh"
module load something || exit
exec python -- "$0" "$@"
'''

python script follows
    
por 27.07.2017 / 17:32