Quando devo usar #! / bin / bash e quando #! / bin / sh?

97

Quando #!/bin/bash é mais apropriado que #!/bin/sh em um script de shell?

    
por Hendré 10.10.2016 / 09:02

6 respostas

143

Resumindo:

  • Existem vários shells que implementam um superconjunto de a especificação sh POSIX . Em sistemas diferentes, /bin/sh pode ser um link para ash, bash, dash, ksh, zsh, & c. (Ele sempre será compatível com sh - nunca csh ou peixe).

  • Contanto que você use apenas sh , você pode (e provavelmente deve) usar #!/bin/sh e o script deve funcionar bem, não importando qual seja a shell.

  • Se você começar a usar recursos específicos do bash (por exemplo, arrays), deverá solicitar especificamente o bash - porque, mesmo que /bin/sh já invoque o bash no seu sistema, talvez não todos os outros sistema, e seu script não será executado lá. (O mesmo se aplica a zsh e ksh.) Você pode usar o shellcheck para identificar os bashisms.

  • Mesmo que o script seja apenas para uso pessoal, talvez você perceba que alguns sistemas operacionais alteram /bin/sh durante as atualizações. no Debian costumava ser bash, mas depois foi substituído por um mínimo de traço. Scripts que usavam bashisms, mas tinham #!/bin/sh de repente quebraram.

No entanto:

  • Mesmo #!/bin/bash não está muito correto. Em sistemas diferentes, o bash pode estar 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 a ferramenta env em si não seja estritamente garantida, o /usr/bin/env ainda funciona em mais sistemas do que o /bin/bash ).

por 21.10.2016 / 05:03
18

Use o shebang correspondente ao shell que você realmente usou para desenvolver e depurar seu script. Ou seja se seu shell de login for bash e você executar seu script como executável no seu terminal, use #!/bin/bash . Não assuma que, como você não usou arrays (ou qualquer que seja o recurso bash do qual você esteja ciente), é seguro escolher o shell que quiser. Existem muitas diferenças sutis entre shells ( echo , funções, loops, you name it) que não podem ser descobertas sem testes apropriados.

Considere isso: se você deixar #!/bin/bash e seus usuários não o tiverem, eles verão uma mensagem de erro clara, algo como

Error: /bin/bash not found

A maioria dos usuários pode corrigir isso em menos de um minuto instalando o pacote apropriado. Por outro lado, se você substituir o shebang por #!/bin/sh e testá-lo em um sistema no qual /bin/sh seja um link simbólico para /bin/bash , seus usuários que não tiverem bash terão problemas. Eles provavelmente verão uma mensagem de erro enigmática como:

Error in script.sh line 123: error parsing token xyz

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ê gostaria de usar um shell diferente no shebang. Uma razão é quando o shell que você usou não é muito difundido. Outra é ganhar desempenho com sh , que é 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, em seguida, altere o shebang.

    
por 10.10.2016 / 16:03
5

Você só deve usar #! /bin/sh .

Você não deve usar extensões bash (ou zsh, ou fish, ou ...) em um script shell, nunca.

Você deve sempre escrever scripts de shell que funcionem com qualquer implementação da linguagem shell (incluindo todos os programas "utilitários" que acompanham o próprio shell). Nos dias de hoje você pode provavelmente tomar POSIX.1-2001 ( não -2008) como autoritativo para o que o shell e utilitários são capazes, mas esteja ciente de que você pode um dia ser chamado para portar seu script para um sistema legado (por exemplo, Solaris ou AIX) cuja shell e utilitários foram congelados por volta de 1992 .

O que, sério?!

Sim, sério.

Aqui está a coisa: Shell é uma linguagem de programação terrível . A única coisa que tem a fazer é que /bin/sh é o único interpretador de scripts que a toda instalação Unix é garantida.

Aqui está a outra coisa: alguma iteração do intérprete central do Perl 5 ( /usr/bin/perl ) é mais provável de estar 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 incluirei o PHP e o Tcl nessa categoria quando comparadas ao shell) também estão mais ou menos disponíveis como o bash e outras shells estendidas.

Portanto, se você tem a opção de escrever um script bash, você tem a opção de usar uma linguagem de programação que não é terrível.

Agora, scripts em shell simples , do tipo que apenas executam alguns programas em uma sequência a partir de uma tarefa cron ou algo assim, não há nada de errado em deixá-los como scripts de shell. Mas scripts de shell simples não precisam de arrays ou funções ou [[ mesmo. E você só deve escrever scripts de shell complicados quando não tiver outra opção. Scripts autoconf, por exemplo, são apropriadamente scripts de shell. Mas esses scripts precisam ser executados em todas as versões de /bin/sh que são relevantes para o programa que está sendo configurado. e isso significa que eles não podem usar extensões. Provavelmente você não precisa se preocupar com antigos Unixes proprietários hoje em dia, mas provavelmente deve se preocupar com os BSDs de código aberto atuais, alguns dos quais não instalam bash por padrão e ambientes incorporados que fornecem apenas um shell mínimo e busybox .

Em conclusão, no momento em que você se encontra querendo um recurso que não está disponível na linguagem de shell portátil, isso é um sinal de que o script se tornou complicado demais para manter um script de shell. Reescreva-o em uma linguagem melhor.

    
por 14.10.2016 / 15:55
3

Geralmente, se o tempo for mais importante que a funcionalidade, você usará o shell mais rápido. sh é frequentemente usado para dash e tende a ser usado para tarefas cron ou tarefas em que cada (nano) segundo conta.

    
por 11.10.2016 / 08:30
2

Para ser ainda mais breve, use sh se a portabilidade na maioria dos sistemas for mais importante e bash se você quiser usar alguns de seus recursos específicos, como matrizes, se a versão do bash oferecer suporte .

    
por 11.10.2016 / 22:36
1
  • sh (para a maioria dos casos), bash se especificamente necessário (ou ksh, ou qualquer outro)

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 alteração que o PATH pode alterar é:

#! / usr / bin / env sh ou
 #! / usr / bin / env bash
ou, por exemplo, scripts perl
 #! / usr / bin / env perl -w

É claro que, quando você tem um motivo para um script NUNCA estar pegando automaticamente um novo PATH, continue codificando-o - e, em seguida, / usr / bin / alguma coisa deve ser o caminho mais provável a ser usado.

    
por 24.11.2016 / 19:41