Qual é a diferença entre #! / Bin / sh e #! / Bin / bash?

281

se eu escrever,

#!/bin/bash
echo "foo"

ou

#!/bin/sh
echo "foo"

ambos produzem o mesmo. Eu vi alguns scripts começando com #!/bin/shou #!/bin/bash. Existe alguma diferença entre eles?

Rahul Virpara
fonte

Respostas:

242

bashe shsão duas conchas diferentes. Basicamente bashé sh, com mais recursos e melhor sintaxe. A maioria dos comandos funciona da mesma forma, mas são diferentes.

Dito isto, você deve perceber que /bin/shna maioria dos sistemas haverá um link simbólico e não será invocado sh. No Ubuntu /bin/shcostumava se conectar bash, comportamento típico nas distribuições Linux, mas agora mudou para o link para outro shell chamado dash . Eu usaria bash, pois esse é praticamente o padrão (ou pelo menos o mais comum, da minha experiência). De fato, surgem problemas quando um script bash será usado #!/bin/shporque o criador do script assume que o link está para bashquando não precisa ser.

Para mais informações, http://man.cx/sh , http://man.cx/bash .

reverendj1
fonte
25
Seu primeiro parágrafo é bastante enganador. "sh" não é um shell, mas um link simbólico para o shell do sistema atualmente configurado , que nos sistemas Linux geralmente é bash ou dash (versões recentes do Ubuntu usando o último).
thomasrutter
19
/bin/shcostumava ser um shell chamado bourne shell em 1977. o bash é um shell compatível com / bin / sh que pode ser usado como um substituto do shell bourne em conformidade com o posix. pt.wikipedia.org/wiki/Bourne_shell
Alex
5
bash é um padrão de fato (muito utilizado), mas não é "padrão"; O sh no Ubuntu usa o dash , que é um shell compatível com Posix, por isso é realmente padrão. Meu conselho é usar o dash o mais rápido possível para scripts, especialmente para scripts do lado do servidor. Embora o bash seja mais expressivo, o traço corre muito mais rápido e é mais seguro.
Rick-777
@ Rick-777 Então devo colocar explicitamente #! / Bin / dash na parte superior dos meus scripts? Também escrevi scripts em que apenas escrevo comandos e executo com ./scriptName e que funcionou bem. O #! / Bin / yourShellHere é necessário?
user137717
@ Rick-777 Nos casos em que excluo qualquer #! / Bin / shellName, nomeiei os arquivos fileName.sh. Isso implicitamente vinculará ao shell de sistema preferido sem declarar #! / Bin / sh?
user137717
82

No Linux e outros sistemas similares ao Unix, você pode escolher vários shells.

O shell é responsável não apenas por desenhar seu pequeno prompt, mas também por interpretar seus comandos, especialmente se você colocar em lógica complicada, como pipes, condicionais e assim por diante.

bash é o shell mais comum usado como shell padrão para usuários de sistemas Linux. É um descendente espiritual de outras conchas usadas ao longo da história do Unix. Seu nome, bash é uma abreviação de Bourne-Again Shell, uma homenagem ao shell Bourne que foi projetado para substituir, embora também incorpore recursos do C Shell e do Korn Shell.

Atualmente, ele é executado a partir de /bin/bash- qualquer sistema com bash o terá aqui.

Mas não são apenas os usuários que usam conchas. Os scripts ( shell scripts ) precisam de shells para interpretá-los. Quando você executa um script de shell, seu sistema precisa iniciar um processo de shell para executar seu script.

O problema é que diferentes shells têm pequenas inconsistências entre eles e, quando se trata de executar scripts, esses podem ser um problema real. O bash possui muitos recursos de script exclusivos apenas do bash e não de outros shells. Tudo bem, se você sempre usar o bash para executar esses scripts. Outros shells podem tentar emular o bash ou aderir ao padrão POSIX, que o bash suporta muito bem (embora inclua suas próprias extensões no).

É possível especificar na parte superior de um script de shell qual shell ele deve ser executado usando um shebang. Um script pode especificar #!/bin/bashna primeira linha, o que significa que o script deve sempre ser executado com bash, em vez de outro shell.

/ bin / sh é um executável que representa o shell do sistema . Na verdade, geralmente é implementado como um link simbólico apontando para o executável para qualquer shell que seja o shell do sistema. O shell do sistema é o tipo do shell padrão que os scripts do sistema devem usar. Nas distribuições Linux, por um longo período, isso geralmente era um link simbólico para o bash , tanto que se tornou uma convenção sempre vincular / bin / sh ao bash ou um shell compatível com o bash. No entanto, nos últimos dois anos, o Debian (e Ubuntu) decidiu mudar o shell do sistema do bash para o dash- um shell semelhante - rompendo com uma longa tradição no Linux (bem, GNU) de usar o bash para / bin / sh. O Dash é visto como um shell mais leve e muito mais rápido, o que pode ser benéfico para a velocidade de inicialização (e outras coisas que exigem muitos scripts de shell, como scripts de instalação de pacotes).

O Dash é razoavelmente compatível com o bash, baseando-se no mesmo padrão POSIX. No entanto, ele não implementa as extensões específicas do bash. Existem scripts existentes que usam #!/bin/sh(o shell do sistema) como shebang, mas que exigem extensões específicas do bash. Atualmente, este é considerado um bug que deve ser corrigido pelo Debian e Ubuntu, que exige que o / bin / sh possa funcionar quando apontado para o traço.

Mesmo que o shell do sistema do Ubuntu esteja apontando para o hífen, seu shell de login como usuário continua sendo debatido no momento. Ou seja, quando você faz login em um emulador de terminal em qualquer lugar do Linux, seu shell de logon será acionado. A velocidade da operação não é um problema quando o shell é usado interativamente, e os usuários estão familiarizados com o bash (e podem ter personalizações específicas do bash no diretório inicial).

O que você deve usar ao escrever scripts

Se o seu script exigir recursos suportados apenas pelo bash, use #!/bin/bash.

Mas, se possível, seria bom garantir que seu script seja compatível com POSIX e utilizá-lo #!/bin/sh, o que deve sempre, de maneira bastante confiável, apontar para o shell do sistema compatível com POSIX preferido em qualquer instalação.

thomasrutter
fonte
18

Além das respostas anteriores, mesmo que /bin/shseja um link simbólico para /bin/bash, #!/bin/shnão é totalmente equivalente a #!/bin/bash.

Na página do manual bash (1) :

"Se o bash for chamado com o nome sh, ele tentará imitar o comportamento de inicialização das versões históricas do sh o mais próximo possível, enquanto estiver em conformidade com o padrão POSIX".

Por exemplo, a sintaxe específica do bash:

 exec  > >(tee logfile.txt)

dá um erro em um shell começando com #!/bin/sh, mesmo com o link simbólico sh-> bash no lugar.

AnkiF
fonte
6

GNU Bash: #!/bin/bash; POSIX Shell: #!/bin/sh.

山 茶树 和 葡萄
fonte
Bem, resposta curta, mas precisa. #
58515 Sergiy Kolodyazhnyy