Por que o Python no Linux requer a linha #! / usr / bin / python?

50

Pergunta bem simples: no Linux, por que o Python exige a linha

#!/usr/bin/python

no início de um arquivo python, já que o Windows não funciona?

O que isso faz? porque a descrição "Links to Python" é um pouco vaga ...

    
por DevRobot 04.11.2015 / 22:48

7 respostas

56

Python não possui nenhum requisito especial no Linux. É o carregador de programas no Unix / Linux que usa a linha "shebang", como é chamado. Isso é realmente um recurso e não uma limitação, mas chegaremos a isso em um momento. A página do Wiki em "shebang" tem mais detalhes, mas vou tentar dar uma visão geral também como uma comparação com o Windows aqui.

Primeiro, vamos analisar a situação no Windows:

  • Quando você tenta abrir ou executar um arquivo, o Windows primeiro examina a extensão desse arquivo. Esta é a parte última do nome do arquivo começando com . No caso de arquivos Python, isso geralmente é .py .
  • O Windows procura a ação a ser tomada com base na extensão do arquivo.
    • Essas informações são registradas no registro do Windows; Quando o Python é instalado, ele normalmente diz ao Windows que .py arquivos devem ser abertos usando o aplicativo Python recém-instalado (ou seja, o interpretador Python).
    • Vários tipos de arquivo possuem comportamentos internos; por exemplo, arquivos executáveis (como o próprio interpretador Python) devem terminar em .exe e .bat arquivos são executados como scripts em lotes do Windows.
    • A ação realizada para um determinado tipo de arquivo é personalizável . Você pode, por exemplo, dizer ao Windows que, em vez de executar .py arquivos usando python.exe , ele deve abri-los com algum outro programa, como o editor de texto notepad.exe .
      • Nesse caso, para executar um script Python, você precisaria manualmente chamar python <scriptname>.py (ou gravar um arquivo .bat para fazer isso para você).

Agora, o que acontece se houver uma linha shebang ( #!/usr/bin/python ou #!/usr/bin/env python ) na parte superior do script Python? Bem, como # é uma linha de comentário em Python, o interpretador Python apenas o ignora. Esse é um dos motivos pelos quais a maioria das linguagens de script usadas no mundo Unix / Linux usa # para iniciar linhas de comentários.

Portanto, é um pouco enganador dizer que o Windows "não precisa" da linha #! ; O Windows não a linha #! e, de fato, depende da extensão do arquivo para dizer o que fazer. Isso tem algumas desvantagens:

  • Você deve nomear scripts Python com .py no final para que eles sejam automaticamente reconhecidos como tal.
  • Não há uma maneira fácil de distinguir os scripts do Python2 dos scripts do Python3.
  • Como observado anteriormente, se você alterar o comportamento de inicialização padrão para o tipo de arquivo .py , o Windows não executará mais esses scripts automaticamente com o Python. Note que isso pode ser feito de forma não intencional.

Agora, vamos ver como o Unix / Linux lança scripts:

A primeira coisa a notar é que o Unix / Linux, ao contrário do Windows, não está tentando "abrir" scripts Python usando um programa em particular, pelo menos conceitualmente; O sistema operacional sabe que o script é algo que pode ser executado por causa de algo chamado "execute bit" (que está fora do escopo desta resposta). Portanto, se você acidentalmente digitar #!/usr/bin/pthon em vez de #!/usr/bin/python , receberá uma mensagem de erro que inclui este texto:

/usr/bin/pthon: bad interpreter: No such file or directory.

A palavra "intérprete" nos dá uma pista sobre o papel da linha shebang (embora tecnicamente o programa especificado possa ser algo diferente de um interpretador, como cat ou um editor de texto). Quando você tenta executar um arquivo, veja o que acontece:

  • O carregador de programas Unix / Linux examina os dois primeiros bytes desse arquivo; se esses dois bytes forem #! , o carregador interpretará o restante da linha shebang (excluindo o próprio shebang) como um comando para lançar um interpretador com o qual executar o conteúdo do arquivo como um script.
  • O carregador de programas inicia o interpretador especificado, alimentando o caminho do arquivo original como um argumento.

Isso tem algumas vantagens:

  • O criador de scripts tem mais controle sobre qual interpretador será usado (o que resolve o problema do Python2 / Python3) e às vezes pode passar um argumento extra para o interpretador (consulte a página do Wiki para obter detalhes).
  • O nome do arquivo do script é ignorado , então você pode nomear os scripts Python como quiser.

Note, finalmente, que o Unix / Linux não precisa da linha shebang para executar um script Python. Lembre-se de que tudo que a linha shebang realmente faz é permitir que o carregador de programas selecione um intérprete. Mas, assim como no Windows, isso pode ser feito manualmente:

python <myscript>
    
por Kyle Strand 05.11.2015 / 23:25
41

A linha que você indicou é usada para informar ao computador que programa / intérprete usar ao executar o arquivo / script diretamente e quaisquer argumentos que devem ser passados para esse programa quando o script é executado. Isto não é, no entanto, um requisito do Python , é um requisito do kernel / sistema linux se você pretende executar o script diretamente (e não passá-lo para o Python pela sintaxe abaixo).

Não é necessário se você vai executar python script.py ou similar. Só é necessário se você pretende executar o script / arquivo diretamente, sem também fornecer o intérprete para usar (como python ).

Para um script Bash, teria algo assim:

#!/bin/bash [optional Bash arguments]
# Bash script code here
...
exit 0;

Isso indicaria ao sistema que, quando isso é executado, ele deve ser executado via /bin/bash , que é uma das linguagens shells / shell-script no sistema.

Para o código Python, no entanto, aqui, você vai querer ter o arquivo executável executado via Python, então você diz qual interpretador você pretende executar nele.

#!/usr/bin/python [optional Python arguments]
# Python code here
...
exit()

Isso, como no caso do Bash, indica que /usr/bin/python deve ser usado (provavelmente é o Python 2 ou o Python 3, dependendo das configurações individuais do sistema).

Dessa forma, você pode executar ./filename.py ou ./executable ou ./scripttorun diretamente.

Sem essa linha no início, e supondo que você tenha definido o arquivo / script como executável e supondo que esteja trabalhando com um script Python, seria necessário executar python filename.py ou similar se não tivesse o script #!/usr/bin/python linha. (Para um script Bash, você teria que fazer bash script.sh , ou similar para outros scripts / idiomas, como Perl, Ruby, etc.)

O realce da sintaxe acima é específico do idioma em cada seção, embora isso realmente não importe.

    
por Thomas Ward 04.11.2015 / 22:53
16

A linha:

#!/usr/bin/python

é chamado de 'shebang' e indica o caminho para o binário do interpretador que será usado para interpretar o restante dos comandos no arquivo. Geralmente é a primeira linha de um script.

Portanto, a linha #!/usr/bin/python indica que o conteúdo do arquivo será interpretado pelo binário python localizado em /usr/bin/python .

Observe que a linha shebang é analisada pelo kernel e, em seguida, o script será chamado como argumento:

python script_name

Da mesma forma, no caso de #!/bin/bash :

bash script_name
    
por heemayl 04.11.2015 / 22:57
7

Tecnicamente, isso não exige isso. Isso requer um caminho para o ambiente onde seu script é executado. Seus futuros scripts seriam melhores para incluir / usr / bin / env, então, especifique python. Isso significa que seu script é executado no ambiente python, não importa onde o Python esteja instalado. Você quer fazer isso por razões de compatibilidade, você não pode ter certeza de que a próxima pessoa com quem você compartilha seu código terá python instalado em usr / bin / python, ou que eles terão permissões para esses arquivos de sistema.

Aqui está um Q & amp; A semelhante ao estouro de pilha .

O que parece no seu script é:

#!/usr/bin/env python

Eu também vejo alguma preocupação em como especificar o python3. Aqui está como fazer isso:

#!/usr/bin/env python3
    
por j0h 05.11.2015 / 17:50
5

No Linux, o Python pode ou não exigir a linha #! (shebang). Isso depende de como os códigos Python são manipulados, seja executando os códigos no modo interativo do Python ou em um script Python.

O modo interativo do Python permite ao usuário digitar e executar códigos Python diretamente, o que não requer a linha shebang. Para executar o modo interativo, abra um Terminal e digite python para o Python 2.X ou python3 para o Python 3.X.

$  python
Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 

$  python3
Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

O script Python permite que o usuário grave e salve os códigos Python em um arquivo de texto simples e, em seguida, execute os códigos posteriormente. Isso pode ou não exigir a linha de shebang. No entanto, existem duas razões conhecidas quando a linha shebang é necessária para usar o script Python no Linux.

  1. para executar códigos Python em um script executável, ou seja, define como os códigos devem ser executados e usar o interpretador;

  2. para executar códigos Python com relação à versão específica do Python, por exemplo, códigos de execução compatíveis com o Python 2.X ou o Python 3.X somente

Pratique com scripts em Python

Abaixo estão a lista e o conteúdo dos arquivos, que usei para mostrar casos em que a linha #! (shebang) é obrigatória ou não é necessária.

$  ls -ln *.py
-rw-rw-r-- 1 1000 1000  94 Dec 14 18:37 hello1.py
-rwxrwxr-x 1 1000 1000 116 Dec 14 18:37 hello2e.py
-rw-rw-r-- 1 1000 1000 116 Dec 14 18:37 hello2.py
-rwxrwxr-x 1 1000 1000 117 Dec 14 18:37 hello3e.py
-rwxrwxr-x 1 1000 1000 120 Dec 14 18:37 hello3m.py
-rw-rw-r-- 1 1000 1000 117 Dec 14 18:37 hello3.py

$  file *.py
hello1.py:  ASCII text
hello2e.py: Python script, ASCII text executable
hello2.py:  Python script, ASCII text executable
hello3e.py: Python script, ASCII text executable
hello3m.py: Python script, UTF-8 Unicode (with BOM) text executable
hello3.py:  Python script, ASCII text executable
  • hello1.py contém apenas o código-fonte.

    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2.py contém o código fonte e a linha shebang.

    #!/usr/bin/env python
    import sys
    sys.stdout.write("Hello from Python %s\n" % (sys.version,))
    print("Hello, World!")
    
  • hello2e.py contém o mesmo que hello2.py e tornou executável.

  • hello3.py contém o mesmo que hello2.py , exceto que está adaptado para ser executado com o Python 3 renomeando a primeira linha para #!/usr/bin/env python3 .

  • hello3e.py contém o mesmo que hello3.py e tornou executável.

  • hello3m.py contém o mesmo que hello3.py e tornou executável, exceto salvo com a opção Write Unicode BOM no editor de texto, por exemplo, Mousepad.

Além deste ponto, o usuário será apresentado com dois métodos para executar os scripts Python. Ambos os métodos foram demonstrados como abaixo.

Método 1: executar com o programa Python

Abaixo estão os comandos e a saída ao executar o código-fonte com Python 2 e Python 3.

$  python hello1.py
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  python3 hello1.py
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

Ambas as versões do Python conseguiram executar o script com sucesso. Portanto, a linha shebang não é necessária ao executar o script Python via python ou python3 .

Método 2: executar como script Python

Abaixo estão os comandos e a saída ao executar o código-fonte com a linha shebang, que não estão adaptados para nenhum dos dois, Python 2 e Python 3, incluindo casos executáveis e não executáveis.

$  ./hello1.py
bash: ./hello1.py: Permission denied

$  ./hello2.py
bash: ./hello2.py: Permission denied

$  ./hello3.py
bash: ./hello3.py: Permission denied

$  ./hello2e.py 
Hello from Python 2.7.6 (default, Jun 22 2015, 18:00:18) 
[GCC 4.8.2]
Hello, World!

$  ./hello3e.py 
Hello from Python 3.4.3 (default, Oct 14 2015, 20:33:09) 
[GCC 4.8.4]
Hello, World!

Os três primeiros scripts falharam porque esses scripts não são executáveis, independentemente de terem a linha shebang ou não (para comprovar, veja Exemplo adicional abaixo). Os dois últimos scripts têm a linha shebang e são executáveis.

Aparentemente, um script que se tornou executável é essencialmente inútil sem a linha shebang. Portanto, a linha shebang é necessária e o script deve ser executável ao executar os códigos Python em um script executável.

Quando o shebang não funciona

No meu exemplo preparado e testado, a execução de hello3m.py como um script executável falhou e retornou um erro.

$  ./hello3m.py 
./hello3m.py: line 1: #!/usr/bin/env: No such file or directory

Esta é uma limitação conhecida de que o shebang não funciona ou se torna inválido. Quando um arquivo é salvo como BOM Unicode (Byte Order Mark), ele não será executado normalmente como um script Python executável.

Exemplo adicional

Este exemplo adicional deve ser tratado apenas como prova de apoio. O usuário deve evitar executar este exemplo, embora o resultado seja inofensivo.

Eu criei outro arquivo chamado hello1e.py , que contém o mesmo que hello1.py e tornou executável. A execução deste script retornou um erro de sintaxe.

$  ./hello1e.py 
./hello1e.py: line 2: syntax error near unexpected token '"Hello from Python %s\n"'
./hello1e.py: line 2: 'sys.stdout.write("Hello from Python %s\n" % (sys.version,))'

Ao executar este script, a princípio, o cursor do mouse será alterado para um sinal de mais e não fará nada na aparência. O erro de sintaxe não será mostrado até que eu clique na área de trabalho ou na janela do Terminal. Em seguida, esse script criará um arquivo sys no mesmo diretório do script.

$  file sys
sys: PostScript document text conforming DSC level 3.0, Level 1

O arquivo sys foi identificado como arquivo PostScript, sem extensão de arquivo. Este arquivo pode ser aberto no visualizador de documentos, ou seja, Evince, e o arquivo realmente continha uma captura de tela da janela que eu tinha clicado anteriormente. Na minha experiência, o arquivo pode ser tão grande quanto alguns megabytes.

Mais uma vez, a linha shebang é necessária e o script deve ser executável ao executar o script Python como um script executável. Caso contrário, o script se comportará mal como descrito acima.

Notas adicionais

O termo "tornado executável" ou "deve ser executável" refere-se à permissão para executar o script.Isso é feito executando o comando chmod +x FILENAME no Terminal ou marcando a opção "Permitir que este arquivo seja executado como um programa" ou algo similar na janela Propriedades , dentro de um gerenciador de arquivos.

Enquanto outras respostas existentes cobriram quase tudo, essa resposta adotou uma abordagem diferente, usando exemplos práticos para explicar o assunto. A sintaxe do código foi escrita com cuidado, de modo que os exemplos pudessem ser executados com o Python 2 ou o Python 3, como é.

Os códigos Python foram adaptados de Usando o Python no Windows e Usando o Python em plataformas Unix , com código adicional de uma linha do onipresente "Hello, World!" programa.

Todos os códigos e comandos foram totalmente testados e funcionam no sistema Xubuntu 14.04, que tinha o Python 2.7 e o Python 3.4 instalados por padrão.

    
por clearkimura 14.12.2015 / 19:19
4

Isso significa que quando esse arquivo é executado, seu computador sabe executá-lo com o programa /usr/bin/python , é assim que você o diferencia de outro idioma, como o bash, onde você faria #!/bin/bash . Isso é para que você possa simplesmente executar:

./[file-to-execute]

E ele saberá com qual arquivo executá-lo, em vez de você precisar especificar com algo como:

python ./[file-to-execute].py

A parte #! geralmente é referenciada como shebang ou crunch bang .

    
por Great Uncle Bulgaria 04.11.2015 / 22:53
1

Se você tiver várias versões do Python instaladas, /usr/bin/env garantirá que o interpretador usado seja o primeiro do $PATH do seu ambiente. A alternativa seria codificar algo como #!/usr/bin/python ;

No Unix, um arquivo executável que deve ser interpretado pode indicar qual interpretador usar, tendo um #! no início da primeira linha, seguido pelo interpretador (e qualquer sinalizador que possa ser necessário).

Esta regra aplica-se apenas ao sistema baseado em UNIX.

    
por orvi 19.12.2015 / 14:34