Quando uso o shebang #!/usr/bin/env pythonpara executar um script, como o sistema sabe qual pythonusar? se procuro um pythoncaminho bin nas variáveis de ambiente, não encontro nada.
env | grep -i python
Quando uso o shebang #!/usr/bin/env pythonpara executar um script, como o sistema sabe qual pythonusar? se procuro um pythoncaminho 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/binou 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 pythonestá 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 pythonem /usr/binem algumas máquinas e /usr/local/binnos outros? Ou você deseja configurá PATH- /home/joe/opt/python-2.5/binlo para usar uma versão específica do Python? Como o kernel não fará a PATHpesquisa 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-commanddeve tomar o nome de um executável como argumento e procurá-lo PATHe executá-lo: o kernel será executado /fixed/path/to/path-lookup-command python /path/to/script. Por acaso, o envcomando 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 envno /usr/bine 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
enve which? desde que também obterá o executável mais qualificado do meu ambiente PATH.
whichencontra o executável e imprime seu caminho. envlocaliza o programa especificado pelo primeiro argumento e o executa, passando os argumentos restantes.
envé uma versão whichessencial 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.pathentre 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']).