Quando uso o shebang #!/usr/bin/env python
para executar um script, como o sistema sabe qual python
usar? se procuro um python
caminho bin nas variáveis de ambiente, não encontro nada.
env | grep -i python
Quando uso o shebang #!/usr/bin/env python
para executar um script, como o sistema sabe qual python
usar? se procuro um python
caminho bin nas variáveis de ambiente, não encontro nada.
env | grep -i python
Respostas:
O shebang espera que um caminho completo para o intérprete seja usado para que a seguinte sintaxe esteja incorreta:
#!python
Definir um caminho completo como este pode funcionar:
#!/usr/local/bin/python
mas seria não portátil como python pode ser instalado em /bin
, /opt/python/bin
ou onde quer outro local.
Usando env
#!/usr/bin/env python
é um método que permite uma maneira portátil de especificar para o sistema operacional um caminho completo equivalente ao local onde python
está localizado pela primeira vez no PATH
.
A linha shebang (de “sharp bang”, ie #!
) é processada pelo kernel. O kernel não quer saber sobre variáveis de ambiente como PATH
. Portanto, o nome na linha shebang deve ser um caminho absoluto para um executável. Você também pode especificar um argumento adicional para passar para esse executável antes do nome do script (com restrições dependentes do sistema, não vou entrar aqui). Por exemplo, para um script Python, você pode especificar
#!/usr/bin/python
na primeira linha, e quando você executar o script, o kernel será executado /usr/bin/python /path/to/script
. Mas isso não é conveniente: você precisa especificar o caminho completo do comando. O que se tem python
em /usr/bin
em algumas máquinas e /usr/local/bin
nos outros? Ou você deseja configurá PATH
- /home/joe/opt/python-2.5/bin
lo para usar uma versão específica do Python? Como o kernel não fará a PATH
pesquisa por você, a idéia é fazer com que o kernel execute um comando que, por sua vez, procure o intérprete desejado no PATH
:
#!/fixed/path/to/path-lookup-command python
Isso path-lookup-command
deve tomar o nome de um executável como argumento e procurá-lo PATH
e executá-lo: o kernel será executado /fixed/path/to/path-lookup-command python /path/to/script
. Por acaso, o env
comando faz exatamente isso. Seu principal objetivo é executar um comando com um ambiente diferente, mas como ele procura o nome do comando $PATH
, é perfeito para o nosso propósito aqui.
Embora isso não é garantido oficialmente, sistemas históricos Unix fornecido env
no /usr/bin
e sistemas modernos têm mantido esse local precisamente por causa do uso generalizado de #!/usr/bin/env
. Portanto, na prática, a maneira de especificar que um script deve ser executado pelo interpretador Python favorito do usuário é
#!/usr/bin/env python
env
e which
? desde que também obterá o executável mais qualificado do meu ambiente PATH.
which
encontra o executável e imprime seu caminho. env
localiza o programa especificado pelo primeiro argumento e o executa, passando os argumentos restantes.
env
é uma versão which
essencial de essencialmente.
Certo, então corra:
env | grep PATH
Seu $ PATH é uma lista de diretórios. O Unix passará por essa lista de diretórios, em ordem, até encontrar "python".
Você pode ver qual diretório ele encontra com o comando 'what':
which python
sys.path
entre um env ativado $ env python3
( ['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
) e ./env/bin/python3
(['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']
).