A linha #!
é usada antes de o script ser executado e, em seguida, ignorado quando o script é executado.
Você está perguntando qual é a diferença entre uma linha shebang e um comentário comum.
Uma linha que começa com #!
é tanto um comentário quanto qualquer outra linha que comece com #
. Isso será verdadeiro se o #!
for a primeira linha do arquivo ou em qualquer outro lugar. #!/bin/sh
tem um efeito , mas não é lido pelo próprio intérprete .
#
não é um comentário em todas as linguagens de programação, mas, como você sabe, é um comentário em shells estilo Bourne incluindo sh
e bash
(assim como a maioria dos shells não Bourne, como% código%). É também um comentário em Python . E é um comentário em uma variedade de arquivos de configuração que não são realmente scripts (como csh
).
Suponha que um script de shell comece com /etc/fstab
. Isso é um comentário, e o interpretador (o shell) ignora tudo na linha após o caractere #!/bin/sh
.
O propósito de uma linha #
não é fornecer informações ao intérprete. O objetivo da linha #!
é informar ao sistema operacional (ou qualquer processo que inicie o interpretador) o que usar como intérprete .
-
Se você invocar o script como um arquivo executável, por exemplo, executando
#!
, o sistema consultará a primeira linha para ver se começa com./script.sh
, seguido por zero ou mais espaços, seguido por um comando. Em caso afirmativo, ele executa esse comando com o nome do script como seu argumento. Neste exemplo, ele executa#!
(ou, tecnicamente,/bin/sh script.sh
). -
Se você invocar o script explicitamente chamando o interpretador, a linha
/bin/sh ./script.sh
nunca será consultada. Então, se você executar#!
, a primeira linha não terá efeito. Se a primeira linha desh script.sh
forscript2.sh
, executar#!/usr/games/nibbles
não tentará abrir o script emsh script2.sh
(masnibbles
will).
Você notará que, em nenhum dos casos, a extensão do script ( ./script2.sh
), se tiver um, afeta o modo como ele é executado. Em um sistema similar ao Unix, isso normalmente não afeta a maneira como o script é executado. Em alguns outros sistemas, como o Windows, a linha .sh
shebang pode ser totalmente ignorada pelo sistema e a extensão pode determinar o que executa os scripts. (Isso não significa que você precisa fornecer extensões de scripts, mas é uma das razões pelas quais, se você fizer isso, elas devem estar corretas.)
#!
foi escolhido para atender a essa finalidade com precisão porque #!
começa um comentário. A linha #
é para o sistema, não para o intérprete, e deve ser ignorada pelo intérprete.
Shebang Line for Bash Scripts
Você (originalmente) disse usar #!
para #!/bin/sh
scripts. Você só deve fazer isso se o script não exigir nenhuma das extensões bash
- bash
precisa ser capaz de executar o script. sh
nem sempre é um link simbólico para sh
. Frequentemente, incluindo em todos os sistemas Debian e Ubuntu remotamente recentes, bash
é um symlink para sh
.
Shebang Line para scripts em Python
Você também disse (na primeira versão da sua pergunta, antes de editar) que inicia seus scripts Python com dash
. Se você quer dizer isso literalmente, então você definitivamente deveria parar de fazer isso. Se #!/bin/sh read by the interpretor
começar com essa linha, executar hello.py
será executado:
/bin/sh read by the interpretor hello.py
./hello.py
tentará executar um script chamado /bin/sh
(com read
como seus argumentos), by the interpretor hello.py
(esperançosamente) não será encontrado, e seu script Python nunca será visto por um interpretador Python.
Se você cometer esse erro, mas não tiver o problema que estou descrevendo, provavelmente estará invocando os scripts do Python especificando explicitamente o interpretador (por exemplo, read
), fazendo com que a primeira linha seja ignorada. Quando você distribui seus scripts para outras pessoas ou os utiliza muito tempo depois, pode não estar claro se isso é necessário para que funcionem. É melhor corrigi-los agora. Ou, pelo menos, remova a primeira linha completamente, para que, quando não funcionarem com python hello.py
, a mensagem de erro faça sentido.
Para scripts em Python, se você souber onde o interpretador Python está (ou será), poderá escrever a linha ./
da mesma maneira:
#!/usr/bin/python
Ou, se for um script do Python 3, você deve especificar #!
, pois python3
é quase sempre Python 2 :
#!/usr/bin/python3
No entanto, o problema é que, enquanto python
deve sempre existir, e /bin/sh
quase sempre existe em sistemas em que /bin/bash
vem com o SO, o Python pode existir em uma variedade de locais.
Portanto, muitos programadores Python usam isso:
#!/usr/bin/env python
(Ou bash
para o Python 3.)
Isso faz com que o script dependa de #!/usr/bin/env python3
estar no "lugar certo", em vez de depender de env
estar no lugar certo. Isso é bom, porque:
-
python
está quase sempre localizado emenv
. - Na maioria dos sistemas, qualquer que seja o
/usr/bin
deve executar seu script é o que aparece primeiro nopython
. A partir dePATH
comhello.py
make#!/usr/bin/env python
run./hello.py
, que é (virtualmente) equivalente a executar/usr/bin/env python hello.py
.
O motivo pelo qual você não pode usar python hello.py
é isso:
- Você deseja que o interpretador especificado seja fornecido por um caminho absoluto (por exemplo, começando com
#!python
). - O processo de chamada executaria
/
no diretório atual. O comportamento de pesquisar o caminho quando o comando não contém uma barra é um comportamento específico do shell.
Ocasionalmente, um script em Python ou outro que não seja um script de shell terá uma linha shebang começando com python
, em que #!/bin/sh ...
é algum outro código. Isso às vezes está correto, porque há algumas maneiras de invocar o shell compatível com Bourne ( ...
) com argumentos para fazer com que ele invoque um interpretador Python. (Um dos argumentos provavelmente conterá sh
.) No entanto, para a maioria dos propósitos, python
é mais simples, mais elegante e mais provável de funcionar da maneira que você deseja.
Shebang Lines em outros idiomas
Muitas linguagens de programação e script, e alguns outros formatos de arquivo, usam #!/usr/bin/env python
como um comentário. Para qualquer um deles, um arquivo no idioma pode ser executado por um programa que o utiliza como argumento especificando o programa na primeira linha após #
.
Em algumas linguagens de programação, #!
normalmente não é um comentário, mas como um caso especial, a primeira linha é ignorada se começar com #
. Isso facilita o uso da sintaxe #!
, mesmo que #!
não torne uma linha um comentário.
Shebang Lines para arquivos que não são executados como scripts
Embora seja menos intuitivo, qualquer arquivo cujo formato de arquivo possa acomodar uma primeira linha que comece com #
seguido pelo caminho completo de um executável pode ter uma linha shebang. Se você fizer isso, e o arquivo estiver marcado como executável, você poderá executá-lo como um programa ... fazendo com que ele seja aberto como um documento.
Algumas aplicações usam esse comportamento intencionalmente. Por exemplo, no VMware, #!
arquivos definem máquinas virtuais. Você pode "executar" uma máquina virtual como se fosse um script porque esses arquivos são marcados como executáveis e possuem uma linha shebang, fazendo com que eles sejam abertos em um utilitário VMware.
Shebang Lines para arquivos que não são executados como scripts, mas funcionam como scripts, de qualquer forma
.vmx
remove arquivos. Não é uma linguagem de script. No entanto, um arquivo que inicia rm
e é marcado como executável pode ser executado e, quando você o executa, #!/bin/rm
é invocado, excluindo-o.
Isso é frequentemente conceituado como "o arquivo é excluído". Mas o arquivo não está realmente rodando. Isso é mais parecido com a situação descrita acima para rm
arquivos.
Ainda assim, como a linha .vmx
facilita a execução de um comando simplista (incluindo argumentos da linha de comando), é possível executar alguns scripts dessa maneira. Como um exemplo simples de um "script" mais sofisticado que #!
, considere:
#!/usr/bin/env tee -a
Isso leva a entrada do usuário de forma interativa, ecoa de volta para o usuário linha por linha e a anexa ao final do arquivo "script".
Útil? Não muito. Conceitualmente interessante? Totalmente! Sim. (Um pouco).
Conceitualmente Conceitos Semelhantes de Programação / Criação de Scripts (apenas por diversão)
-
Scripts / programas que são vários idiomas de uma só vez , por exemplo, para simular a funcionalidade do hashbang em SOs que não o têm .
(Esses programas são chamados poliglotas , mas isso não deve ser confundido com o outro sentido de poliglota no desenvolvimento de software , um programa / projeto no qual diferentes partes são escritas em diferentes idiomas.
-
Metacommands em QBasic / QuickBASIC, que sinalizou para o compilador (para código compilado) opções para geração de código, mas faziam parte dos comentários e, portanto, eram ignorados durante a compilação / interpretação real.