Como o / usr / bin / env sabe qual programa usar?

58

Quando eu uso o shebang #!/usr/bin/env python para executar um script, como o sistema sabe qual python usar? se eu procurar por um caminho python bin nas variáveis de ambiente, não encontro nada.

env | grep -i python
    
por tMC 06.05.2011 / 15:46

3 respostas

51

O shebang espera um caminho completo para o intérprete usar, então a seguinte sintaxe seria incorreta:

#!python

Definir um caminho completo como este pode funcionar:

#!/usr/local/bin/python

mas não seria portátil, pois o python pode ser instalado em /bin , /opt/python/bin ou qualquer outro local.

Usando env

#!/usr/bin/env python

é um método que permite que uma forma portátil especifique para o sistema operacional um caminho completo equivalente àquele em que python está primeiro localizado em PATH .

    
por 06.05.2011 / 17:26
50

A linha shebang (de “sharp bang”, ou seja, #! ) é processada pela núcleo. 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 entrarei aqui). Por exemplo, para um script Python, você pode especificar

#!/usr/bin/python

na primeira linha, e quando você executar o script, o kernel executará /usr/bin/python /path/to/script . Mas isso não é conveniente: você precisa especificar o caminho completo do comando. E se você tiver python em /usr/bin em algumas máquinas e /usr/local/bin em outras? Ou você deseja definir seu PATH para /home/joe/opt/python-2.5/bin para usar uma versão específica do Python? Como o kernel não fará a consulta PATH para você, a idéia é fazer com que o kernel execute um comando que procura o interpretador desejado no PATH :

#!/fixed/path/to/path-lookup-command python

Esse path-lookup-command deve ter o nome de um executável como um argumento e procurá-lo em PATH e executá-lo: o kernel executará /fixed/path/to/path-lookup-command python /path/to/script . Por acaso, o comando env faz exatamente isso. Seu principal objetivo é executar um comando com um ambiente diferente, mas, como ele procura o nome do comando em $PATH , é perfeito para nosso propósito aqui.

Embora isso não seja oficialmente garantido, os sistemas históricos Unix forneceram env em /usr/bin , e os sistemas modernos mantiveram essa localização precisamente devido ao uso generalizado de #!/usr/bin/env . Então, na prática, a maneira de especificar que um script deve ser executado pelo interpretador Python favorito do usuário é

#!/usr/bin/env python
    
por 06.05.2011 / 18:29
6

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 encontra com o comando 'which':

which python
    
por 06.05.2011 / 16:47