Quando é #!/bin/bash
mais apropriado do que #!/bin/sh
em um script de shell?
linux
shell-script
Hendré
fonte
fonte
bash
funções e sintaxe, em vez desh
funções e sintaxe.vim
irá destacarbash
isis se o seu script tiver o#!/bin/sh
shebang. Eu só mudo parabash
se as coisas ficarem peludas o suficiente para começar a precisar dos recursos do bash.$(...)
é particularmente desagradável. Além disso, alguns deles são sutis [<(...)
ecmd >& file
não obter qualquer realce de erros, por exemplo, eles simplesmente não têm destaque especial para o que eles significam, com ou semg:is_bash
]Respostas:
Em resumo:
Existem vários shells que implementam um superconjunto da especificação sh do POSIX . Em sistemas diferentes,
/bin/sh
pode haver um link para ash, bash, dash, ksh, zsh, etc. (Porém, sempre será compatível com sh - nunca csh ou fish.)Contanto que você atenha
sh
apenas aos recursos, você pode (e provavelmente deve) usar#!/bin/sh
e o script deve funcionar bem, independentemente do shell.Se você começar a usar recursos específicos do bash (por exemplo, matrizes), solicite especificamente o bash - porque, mesmo que
/bin/sh
já chame o bash no seu sistema, talvez não no sistema de todos os outros , e seu script não será executado lá. (É claro que o mesmo se aplica a zsh e ksh.) Você pode usar a verificação de shell para identificar bashismos.Mesmo que o script seja apenas para uso pessoal, você pode notar que alguns SOs mudam
/bin/sh
durante as atualizações - por exemplo, no Debian, costumava ser bash, mas depois foi substituído por um traço mínimo. Scripts que usavam basismos, mas que haviam#!/bin/sh
subitamente quebrado.Contudo:
Mesmo
#!/bin/bash
não é muito correto. Em sistemas diferentes, o bash pode residir em/usr/bin
ou/usr/pkg/bin
ou/usr/local/bin
.Uma opção mais confiável é
#!/usr/bin/env bash
, que usa $ PATH. (Embora aenv
ferramenta em si também não seja estritamente garantida,/usr/bin/env
ainda funciona em mais sistemas do que em outros/bin/bash
).fonte
/bin/sh
então ele tentará imitar ossh
recursos (consulte a página de manual ), não tendo certeza de que os recursos específicos do bash estejam disponíveis neste modo.env
tool é uma ferramenta posix que deve ser encontrada na maioria das distribuições, mas não tenho certeza, pois algumas podem não respeitar o posix./bin
: "Os aplicativos devem observar que o PATH padrão para o shell não pode ser assumido como / bin / sh ou / usr / bin / sh, e deve ser determinado interrogando o PATH retornado pelo getconf PATH, garantindo que o nome do caminho retornado seja um nome de caminho absoluto e não um shell interno ". Veja também esta pergunta e, especificamente, esta resposta .#!
scripts funcionarem?echo foo ^ cat
emitefoo ^ cat
no POSIX sh e emite apenasfoo
em Bourne (como^
é um caractere de pipe).Use o shebang correspondente ao shell que você realmente usou para desenvolver e depurar seu script. Ou seja, se o seu shell de login é
bash
e você executa seu script como executável no seu terminal, use#!/bin/bash
. Não assuma apenas que, como você não usou matrizes (ou qualquerbash
recurso que você conheça), você pode escolher o shell que quiser. Existem muitas diferenças sutis entre shells (echo
funções, loops, etc.) que não podem ser descobertas sem testes adequados.Considere o seguinte: se você sair
#!/bin/bash
e os usuários não o tiverem, eles verão uma mensagem de erro clara, algo comoA maioria dos usuários pode corrigir isso em um minuto instalando o pacote apropriado. Por outro lado, se você substituir o shebang
#!/bin/sh
e testá-lo em um sistema em que/bin/sh
existe um link simbólico/bin/bash
, seus usuários que não possuembash
terão problemas. Eles provavelmente verão uma mensagem de erro enigmática como:Isso pode levar horas para ser corrigido, e não haverá nenhuma pista sobre qual shell eles deveriam ter usado.
Não há muitas razões pelas quais você deseja usar um shell diferente no shebang. Uma razão é quando o shell que você usou não é generalizado. Outra é obter um desempenho
sh
significativamente mais rápido em alguns sistemas, E seu script será um gargalo de desempenho. Nesse caso, teste seu script completamente com o shell de destino e altere o shebang.fonte
Você só deve usar sempre
#! /bin/sh
.Você nunca deve usar extensões bash (ou zsh, ou fish ou ...) em um script de shell.
Você só deve escrever scripts de shell que funcionem com qualquer implementação da linguagem do shell (incluindo todos os programas "utilitários" que acompanham o próprio shell). Atualmente, você provavelmente pode considerar o POSIX.1-2001 ( não -2008) como autoritário para o que o shell e os utilitários são capazes, mas esteja ciente de que um dia você poderá ser chamado para portar seu script para um sistema legado (por exemplo, Solaris ou AIX) cuja concha e utilitários foram congelados por volta de 1992.
Sério ?!
Sim seriamente.
Aqui está a coisa: Shell é uma linguagem de programação terrível . A única coisa que
/bin/sh
vale a pena é o único e único interpretador de script que é garantido que toda instalação do Unix possui.Aqui está outra coisa:
/usr/bin/perl
é mais provável que alguma iteração do interpretador principal do Perl 5 ( ) esteja disponível em uma instalação Unix selecionada aleatoriamente do que(/(usr|opt)(/(local|sfw|pkg)?)?/bin/bash
é. Outras boas linguagens de script (Python, Ruby, node.js, etc. - inclusive incluímos PHP e Tcl nessa categoria quando comparados ao shell) também estão disponíveis como o bash e outros shells estendidos.Portanto, se você tiver a opção de escrever um script bash, poderá usar uma linguagem de programação que não seja terrível.
Agora, scripts shell simples , do tipo que apenas executam alguns programas em uma sequência de um trabalho cron ou algo assim, não há nada de errado em deixá-los como scripts shell. Mas scripts shell simples não precisam de matrizes, funções ou
[[
até mesmo. E você só deve escrever scripts de shell complicados quando não tiver outra opção. Os scripts do Autoconf, por exemplo, ainda são apropriadamente scripts shell. Mas esses scripts precisam ser executados em todas as encarnações/bin/sh
relevantes para o programa que está sendo configurado. e isso significa que eles não podem usar nenhuma extensão. Você provavelmente não precisa se preocupar com Unixes proprietários antigos atualmente, mas provavelmente deve se preocupar com os BSDs de código aberto atuais, alguns dos quais não são instaladosbash
por padrão, e ambientes incorporados que fornecem apenas um mínimo de shell ebusybox
.Concluindo, no momento em que você se encontra querendo um recurso que não está disponível na linguagem shell portátil, isso é um sinal de que o script se tornou muito complicado para permanecer um script shell. Reescreva-o em um idioma melhor.
fonte
sh
. Isso, no entanto, está muito longe de afirmar que você nunca deve usar outras conchas. Existem milhares (provavelmente muito mais) de scripts escritos todos os dias e a grande maioria deles só será executada em uma única máquina. Seu conselho faz sentido no código de produção, mas não nos trabalhos diários "sysdaminy" para os quais a maioria dos scripts é escrita. Se eu souber que meu script só será usado por mim e em uma máquina Linux, o bash está bom.Geralmente, se o tempo for mais importante que a funcionalidade, você usará o shell mais rápido. O sh é frequentemente aliasado ao dash e tende a ser usado para tarefas cron do root ou operações em lote, onde cada (nano) segundo conta.
fonte
Para ser ainda mais breve, use
sh
se a portabilidade na maioria dos sistemas é mais importante ebash
se você deseja usar alguns de seus recursos específicos, como matrizes, se a versão do bash suportar.fonte
O caminho mais seguro. quando codificado, seria / usr / bin /,
shellOfChoice
mas uma nova convenção que estou tentando usar sempre agora - como 'locais padrão' por meio de uma mudança, PATH pode mudar é:#! / usr / bin / env sh ou
#! / usr / bin / env bash
ou, por exemplo, scripts perl
#! / usr / bin / env perl -w
Obviamente, quando você tem uma razão para um script NUNCA estar automaticamente pegando um novo PATH, continue a codificá-lo - e / usr / bin / algo deve ser o caminho mais provável a ser usado.
fonte