Por que você precisa colocar #! / Bin / bash no início de um arquivo de script?


487

Eu criei scripts Bash antes e todos eles correram bem sem #!/bin/bashno começo.

Qual é o sentido de colocá-lo? As coisas seriam diferentes?

Além disso, como você pronuncia #? Eu sei que isso !é pronunciado como "bang".

Como se #!pronuncia?


8
Você não precisa e não deveria, a menos que não tenha escolha. Use '#! / Bin / sh' enquanto puder e aprenda sobre a diferença entre um shell (POSIX) e o bash. Chegará um dia antes do seu currículo aumentar muito mais, quando você se encontrar em um sistema com um shell diferente e ainda desejar que seus scripts funcionem.
Jens

50
É pronunciado "Hash-Bang" ou "She-Bang".
Beachhouse

22
Eu acho que vale a pena notar que isso só é executado se você executar seu script como um executável. Portanto, se você definir o sinalizador executável e digitar ./yourscript.extension, por exemplo, ./helloworld.pyou ./helloworld.sh, ele procurará o intérprete na linha superior, o que seria #!/bin/pythonou !#/bin/bash, enquanto, ao executar o script python helloworld.py, a primeira linha não será observada porque é comentada Fora. Portanto, é uma sequência especial para o shell / kernel.
JFA

@JFA há uma alteração na sequência entre o bash e o python, ao usar! # Para python e #! para festança?
AAI

1
@AjeyaAnand não, era um erro de digitação, boa captura
JFA

Respostas:


426

É uma convenção para que o * nix shell saiba que tipo de intérprete executar.

Por exemplo, os sabores mais antigos do ATT padronizaram sh (o shell Bourne), enquanto as versões mais antigas do BSD padronizaram o csh (o shell C).

Ainda hoje (onde a maioria dos sistemas roda bash, o "Bourne Again Shell" ), os scripts podem estar em bash, python, perl, ruby, PHP, etc, etc. Por exemplo, você pode ver #!/bin/perlou #!/bin/perl5.

PS: O ponto de exclamação ( !) é carinhosamente chamado de "bang" . O símbolo de comentário do shell ( #) às vezes é chamado de "hash" .

PPS: Lembre-se - em * nix, associar um sufixo a um tipo de arquivo é apenas uma convenção , não uma "regra" . Um executável pode ser um programa binário, qualquer um dos milhões de tipos de script e outras coisas também. Daí a necessidade de #!/bin/bash.


1
Eu descobri algo mais útil, $ #. Como se chama isso?
Node ninja

91
O shebang não é uma convenção de shell , é interpretado pelo kernel ao manipular o execve(2)syscall; então o shebang é uma convenção de kernel , não uma convenção de shell.
Basile Starynkevitch

10
Além disso, ajuda alguns editores como o Vim a determinar o idioma para destaque da sintaxe se o arquivo não tiver uma extensão. Sem o shebang, o Vim exibirá um script bash igual ao arquivo de texto sem formatação.
Aaron Blenkush

1
Isso me faz pensar se você precisa adicionar #!/bin/shcoisas .profilee coisas que são onload #
Kolob Canyon

5
Então ... hash-bang-slash-bin-slash-bash ?
Bernat

135

Para ser mais preciso, o shebang #! , quando são os dois primeiros bytes de um arquivo executável ( x modo ), é interpretado pela chamada de sistema execve (2) (que executa programas). Mas a especificação POSIX paraexecve não menciona o shebang.

Ele deve ser seguido por um caminho de arquivo de um interpretador executável (que BTW pode até ser relativo, mas na maioria das vezes é absoluto).

Um bom truque (ou talvez não tão bom ) para encontrar um intérprete (por exemplo python) no usuário $PATHé usar o envprograma (sempre /usr/bin/envem todo o Linux) como por exemplo

 #!/usr/bin/env python

Qualquer executável ELF pode ser um intérprete. Você pode até usar #!/bin/catou #!/bin/truese quiser! (mas isso geralmente seria inútil)


8
Veja esta pergunta para uma discussão sobre o #!/usr/bin/envhack.
Keith Thompson

se eu quiser passar um argumento para python, como faço isso, na verdade eu quero executar #!/usr/bin/env bash -x. Como faço isso ?
Indianwebdevil

sua simples eu me encontrei, basta adicionar o param depois disso#!/usr/bin/env bash -x
indianwebdevil

bashé quase sempre a /bin/bashque o seu shebang deve ser#!/bin/bash -x
Basile Starynkevitch

50

Chama-se shebang . No unix-speak, # é chamado sharp (como na música) ou hash (como hashtags no twitter) e! é chamado bang. (Você pode realmente referenciar seu comando shell anterior com !!, chamado bang-bang). Então, quando reunidos, você obtém haSH-BANG ou shebang.

A parte após o #! diz ao Unix qual programa usar para executá-lo. Se não for especificado, ele tentará com o bash (ou sh, ou zsh, ou qualquer que seja a sua variável $ SHELL), mas se estiver lá, ele usará esse programa. Além disso, # é um comentário na maioria dos idiomas; portanto, a linha é ignorada na execução subsequente.


2
Se eu já estou no bash, ele inicia outra instância do bash se vir #! / Bin / bash? E se eu já estiver no bash e deixar de fora? Existe alguma diferença?
node ninja

2
@javascriptninja de qualquer maneira, inicia um novo shell bash. No caso do bash, realmente não há diferença, desde que você já esteja usando o bash. O shebang realmente importa se (a) você precisar executar algo que não seja apenas um shell, como python ou perl, ou (b) você não usar o shell bash (ou seja, usar o zsh), mas precisar execute algo que exija ser executado no bash.
precisa saber é o seguinte

No entanto, na minha opinião, é uma boa prática incluir o shebang, para que alguém que esteja lendo o código saiba o que está acontecendo.
precisa saber é o seguinte

2
Errado: execve(2)syscall não usa a $SHELLvariável É o kernel que está interpretando o shebang.
Basile Starynkevitch

1
@BasileStarynkevitch está correto, o elf loader no kernel interpreta o shebang. Eu estava afirmando que $ SHELL seria usado se nenhum shebang fosse fornecido.
austin1howard

19

O shebang é uma diretiva para o carregador usar o programa especificado após o #!como intérprete do arquivo em questão quando você tenta executá-lo. Portanto, se você tentar executar um arquivo chamado foo.shque tem #!/bin/bashno topo, o comando real que é executado é /bin/bash foo.sh. Essa é uma maneira flexível de usar diferentes intérpretes para diferentes programas. Isso é algo implementado no nível do sistema e a API no nível do usuário é a convenção shebang.

Também vale a pena saber que o shebang é um número mágico - um número legível por humanos que identifica o arquivo como um script para o intérprete fornecido.

Seu ponto de vista sobre "trabalhar" mesmo sem o shebang é apenas porque o programa em questão é um script de shell escrito para o mesmo shell que você está usando. Por exemplo, você pode muito bem escrever um arquivo javascript e, em seguida, colocar um #! /usr/bin/js(ou algo semelhante) para ter um "script Shell" javascript.


18

O sistema operacional usa o shell padrão para executar seu script de shell. Então, ao mencionar o caminho do shell no início do script, você está pedindo ao sistema operacional para usar esse shell específico. Também é útil para portabilidade .


15

Toda distribuição tem um shell padrão. Bash é o padrão na maioria dos sistemas. Se você trabalha em um sistema que possui um shell padrão diferente, os scripts podem não funcionar como planejado se forem escritos especificamente para o Bash.

O Bash evoluiu ao longo dos anos, recebendo o código de kshe sh.

Adicionando #!/bin/bashcomo a primeira linha do seu script, o sistema operacional deve chamar o especificado shellpara executar os comandos a seguir no script.

#! é freqüentemente chamado de "hash-bang", "she-bang" ou "sha-bang".


9

É chamado de shebang . Consiste em um sinal numérico e um caractere de ponto de exclamação (#!), Seguido pelo caminho completo para o intérprete, como / bin / bash. Todos os scripts no UNIX e Linux são executados usando o intérprete especificado em uma primeira linha.



0

Pode ser útil para alguém que usa um sistema diferente que não possui essa biblioteca prontamente disponível. Se isso não for declarado e você tiver algumas funções em seu script que não são suportadas por esse sistema, você deve declarar # / bin / bash. Eu já tive esse problema antes no trabalho e agora apenas o incluo como prática.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.