bash myscript.sh é executado no bash, mas a primeira linha é #! / usr / bin / sh

5

Eu tenho um script semelhante ao seguinte:

#!/usr/bin/sh

var="ABC"
if [ $var == "ABC" ]
then
   echo True
else
   echo False
fi

O código acima não funciona no Solaris Sparc e no Solaris X64. Está mostrando == undefined. O código acima funciona bem Se eu substituir == por = .

O mais estranho é que se eu corri acima do código sem nenhuma mudança seguindo o método, está funcionando.

#bash test.sh

De acordo com o meu entendimento, o script não deve funcionar nem com o bash, pois no topo do script estou usando #!/bin/sh , que não suporta o == como o operador de comparação.

Alguém por favor pode explicar por que funciona quando estou executando o script como mencionado acima.

Nota: estou ciente de que o bash reconhece == e = .

    
por Abhijeet 08.08.2012 / 16:11

2 respostas

11

A primeira linha do script é chamada de #! line (às vezes chamada de "shebang" linha).

É usado apenas quando um script é executado diretamente, como em

./test.sh

Explicação

Quando você executa um executável, o sistema operacional analisa os dois primeiros bytes para informar que tipo de programa é.

Quando você corre

./test.sh

o sistema operacional vê que os dois primeiros bytes de ./test.sh são #! , então ele sabe que o programa é um script.

Ele lê o resto da linha para ver qual shell 1 deve ser usado para executar o script. Nesse caso, o resto da linha é /usr/bin/sh , então é executado /usr/bin/sh test.sh 2 .

Quando você corre

bash test.sh

ele encontra o bash em /usr/bin/bash 3 . Ele vê que os primeiros dois bytes de /usr/bin/bash não são #! , portanto, ele executa /usr/bin/bash test.sh sem sequer olhar para a primeira linha de test.sh.

Em ambos os casos, sh e bash realmente ignoram a linha shebang porque qualquer linha que comece com # é um comentário. O # só tem esse efeito mágico por causa do sistema operacional, não do shell.

Mais informações:

Notas de rodapé:

  1. Na verdade, pode ser qualquer programa, não precisa ser um shell.
  2. Na verdade, mais como execl("./test.sh", "/usr/bin/sh", "./test.sh", NULL) .
  3. /bin/sh na maioria dos sistemas Linux, mas a questão era sobre o Solaris.
por 08.08.2012 / 16:31
6

Executar o script com o bash (executando bash test.sh ) significa que o script é interpretado com o bash, não com o shell Bourne (/ bin / sh). É por isso que funciona. Bash ignora o #! / Bin / sh porque é um comentário. É apenas o seu carregador de programas do sistema operacional que inicia / bin / sh se você executar o script de shell sem bash (executando ./test.sh por exemplo).

    
por 08.08.2012 / 16:31