Na maioria dos scripts de shell que eu já vi (além dos que ainda não escrevi), notei que o shebang está definido como #!/bin/sh
. Isso realmente não me surpreende em scripts mais antigos, mas também existe em scripts relativamente novos.
Existe alguma razão para preferir a /bin/sh
substituição /bin/bash
, uma vez que bash
é bastante onipresente e muitas vezes padrão em muitas máquinas Linux e BSD que remontam a mais de uma década?
/bin/sh
se você não usarbash
funções específicas . Um dia você pode ter que usar uma das seu script em um sistema no qual não está instalado (servidor remoto, computador embutido ...)...the answers so far are fairly subjective...
Uma declaração "subjetiva" é essencialmente baseada em opinião por definição./bin/bash
só deve ser usado quando o bash for explicitamente necessário. Em mais de 40 anos como desenvolvedor, muito antesbash
, eu quase nunca precisava dele explicitamente , exceto nos testes. (Também me esforço para evitar extensões de shell, mas a maioria dos meus scripts é destinada à distribuição.) Muitos scripts na rede também devem ser usados para uso amplo.Respostas:
/bin
.fonte
/bin/sh
é mais rápido se não forbash
, ainda existem alguns sistemas como OS / X ou RHEL onde/bin/sh
estábash
./bin/sh
é/bin/bash
. A mudança do Ubuntu do bash para o dash quebrou todos eles.#!/bin/bash
se quisessem o Bash (nada de errado nisso!). A mudança foi feita principalmente no upstream no Debian. Melhorou a experiência do usuário, teve um impacto mensurável no tempo de inicialização do sistema. Também impactou positivamente a segurança, consulte "Shellshock".A maioria dos scripts de sistema (relacionados ao Debian: Ubuntu, Mint, etc.) Linux são escritos para serem executados no traço mais rápido, que é o padrão / bin / sh nesses sistemas. O motivo é duplo:
Velocidade do sistema. Um código menor de traço carrega mais rápido e também roda mais rápido. Com algum (pequeno?) Esforço adicional (custo) para programadores de shell scripts.
Segurança. Ter diversidade de conchas ajuda a resiliência a bugs. Os sistemas Debian geralmente não eram vulneráveis ao shellshock porque o shell padrão não tinha essa vulnerabilidade.
O Bash é realmente o shell padrão para os usuários , pois é mais poderoso e possui muito mais elementos para facilitar a codificação. Também é o padrão
sh
no Mac OS (o link de / bin / sh). No entanto, chamarbash
com o nome do link desh
faz com que seja iniciado como um shell compatível com posix.fonte
eval
, com a exposição de segurança correspondente; de forma semelhante, sem suporte embutido expressão regular, pode-se precisar de usar comandos externos (a uma perda de desempenho pesado) para combinar mesmo dentro de uma única linha, etcOutros apontaram que as premissas da pergunta, que o shell Bourne Again é padrão e onipresente, estão totalmente erradas.
Além disso, existem realmente boas razões para usar algo diferente do shell Bourne Again para interpretar scripts de shell. Esses motivos motivaram o grande projeto do Ubuntu e do Debian, ao longo de vários anos, a remover bashisms e a executar o máximo de scripts de shell pela inicialização do sistema (que era um monte de scripts de shell com o System 5
rc
) e a instalação / remoção de pacotes usa o Shell Debian Almquist em vez do shell Bourne Again.Simplificando: o shell Bourne Again, cheio de recursos interativos, não é o interpretador de shell mais rápido para um script de shell compatível com POSIX. Portanto, se alguém puder fazer seus scripts de shell serem compatíveis com POSIX, interpretando-os com um programa mais leve, como o shell Debian Almquist, o sistema de alguém terá um desempenho melhor. (No final, o Debian teve que fazer pequenos ajustes no shell Almquist, para adicionar suporte a algumas construções de shell não POSIX que eram simplesmente muito profundas e amplamente incorporadas e úteis demais para se livrar.)
O resultado disso tudo foi um grande ganho no desempenho do bootstrap.
Portanto, existem duas classes distintas de shell a serem consideradas aqui:
Observe que falar sobre isso como "preferir
/bin/sh
" é simplista demais. O Debian realmente tinha pelo menos dois objetivos:Em face dos administradores que usam o shell Debian Almquist, o shell Z (no modo POSIX), o shell Bourne Again (no modo POSIX), o shell MirBSD Korn e outros como
/bin/sh
, havia…... tornar os scripts o mais portável possível, para que mudar o que foi
/bin/sh
mapeado não estrague as coisas; ou... criar scripts não portáteis direcione explicitamente o programa de intérprete correto , em vez de simplesmente esperar esse
/bin/sh
mapa para ele.Estava tornando o shell Debian Almquist o mapeamento padrão para o
/bin/sh
invés do Bourne Shell, de modo que os scripts que eram compatíveis com POSIX (ou, mais apropriadamente, com conformidade com o Manual de Políticas Debian) rodavam mais rapidamente.E, é claro, quando alguém entra nisso, pode ir muito além; como considerar as vantagens e desvantagens da eficiência
/bin/true
e/usr/bin/clear
ser scripts de shell ou programas compilados. Mas isso está além do escopo desta resposta, felizmente. ☺Nada disso é muito novo, nem mesmo específico do Unix, é claro. Antes da virada do século, escrevi e publiquei um intérprete de linha de comando que apresentava sabores "interativos" e "não interativos", explicando essa mesma divisão em seu documento e observando a diferença entre as variáveis de ambiente
COMSPEC
eOS2_SHELL
. Da mesma forma, a discussão sobre remoção de bashisms no System V do Debianrc
e os scripts de instalação / remoção de pacotes remonta aos anos 90.Leitura adicional
/bin/sh
. Wiki do Ubuntu./bin/sh
. Wiki do Debian.fonte
Schily Bourne Shell
página de manual, consulte schilytools.sourceforge.net/bosh.html, são adequados para permitir que as pessoas entendam como escrever um script portátil (que depende apenasBourne Shell features
de 1989). O que eu fiz foi mencionar todos os aprimoramentos que não estavam nos antigos Bourne Shells. BTW: Também estou interessado em conhecer uma lista de basismos em traço.Sim. A excelente resposta de @ Marco descreve isso muito bem.
Ao escrever seus próprios scripts, você deve apontar o shebang para a coisa mais geral contra a qual você testou.
No meu sistema (Centos 6.6),
sh
está vinculado abash
:Isso significa que eu sempre uso
#!/bin/bash
no meu shebang, a menos que tenha verificado que não tenho bashims no meu script.Ao definir o shebang para
#!/bin/sh
você, você promete que o script funcionará com todas as implementações desh
.Essa é uma promessa muito maior do que dizer que o script funcionará com o bash.
Aqui está um exemplo de script que se comportará incorretamente, dependendo de qual
sh
implementação o sistema está usando:Ao usar
bash
o script, será impresso:Ao usar
dash
o script, será impresso:Se eu quiser usar
#!/bin/sh
o que preciso fazer?checkbashisms
- Observe que isso não encontrará todos os bashims. Não encontrou o basismo no meu script acimash
implementação. Normalmente testo comdash
, no entanto, espero que alguns basismos ou traços ainda possam passar despercebidos.A página DashAsBinSh no wiki do Ubuntu tem muitas informações interessantes.
fonte
/bin/sh
; apenas os compatíveis com POSIX.O único motivo restante para escrever um shell script, em vez de um script em uma linguagem mais poderosa e ergonômica, é se a portabilidade para sistemas legados com um conjunto desconhecido de software instalado é mais importante do que qualquer outro fator .
/bin/sh
é o único intérprete de script disponível em tudo o que se chama Unix. Mas em uma enorme quantidade de sistemas legados,/bin/sh
e os utilitários associados nem mesmo são compatíveis com a especificação "shell and utilities" POSIX.1-1996, muito menos algo mais moderno. As ferramentas compatíveis com o padrão são um complemento opcional, instalado em/usr/xpg4
ou em algum local não óbvio. 1 Os scripts para a linguagem shell do subconjunto portátil são ainda mais entediantes e propensos a erros do que os scripts para a linguagem shell POSIX. (Leia umconfigure
script gerado pelo Autoconf em algum momento, se você não acredita em mim. Apenas a configuração deve ser suficiente para convencê-lo.)Porém, se você puder assumir que outro intérprete de script está instalado (por exemplo, Bash), poderá assumir que um intérprete está instalado para uma melhor linguagem de script . Perl, por exemplo, é mais provável que esteja disponível do que o Bash.
Portanto, você nunca deve escrever um
#! /bin/bash
script, porque se essa é uma opção, um idioma melhor também é uma opção.1 Por exemplo, o Solaris 10 e versões anteriores enviavam o shell Bourne original como
/bin/sh
. Fui informado de que o Solaris 11 o atualizou para ksh93.fonte
/bin/sh
é POSIX.1-1996, mas na verdade um shell Bourne original da sintaxe pré-POSIX. Isso dificulta muito a execução dos scripts com esses lançamentos. Os scripts portáteis no Solaris usariam, o que não será muito portátil em outros sistemas operacionais. No Solaris mais recente, o Oracle Solaris 11 lançado pela primeira vez em 2011, é um moderno que está em conformidade com as especificações recentes do POSIX e possui muitas extensões modernas.#!/bin/sh
#!/usr/xpg4/bin/sh
/bin/sh
ksh93
ash
que é fornecido com o busybox), e eu costumo pensar que o zwol está certo de que o perl está mais disponível do que o bash.bash
estiver disponível, então será uma linguagem melhor para que você nunca escreva nenhumbash
código". Além disso, como aponta @sixtyfootersdude, você deve sempre usar, a#!/bin/bash
menos que tenha testado se seu script funciona com qualquer shell POSIX.Você realmente deveria estar usando
ou
dessa forma, você invoca um dos shell pela maneira como eles são instalados nesse sistema.
Para ser super seguro ( por exemplo, em casos de reinicialização por usuário único), use o
sh
contráriobash
.fonte
the advantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH. The disadvantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH.
Isso provavelmente também se aplica ash
ebash
.#!/bin/env
nada em um script portátil. É perfeitamente razoável supor que/bin/sh
existe e é um shell compatível com POSIX em funcionamento. Por outro lado, nenhum dos meus sistemas possui a/bin/env
./bin/sh
. O POSIX não exige isso e define outras regras para obter um ambiente compatível com POSIX em uma plataforma certificada POSIX./usr/bin/env
não está universalmente disponível ...