Quando sh é um link simbólico para bash ou dash, o bash se limita à conformidade com POSIX, portanto deve ser 100% compatível com sh?

8

De Diferença entre bash e sh :

ABck à pergunta: Se você tiver /bin/shum link para o bash, o bash não se comportará da mesma maneira quando chamado, /bin/shcomo é chamado quando /bin/bash. Quando chamado como sh, ele se limitará principalmente à conformidade com POSIX, além de um conjunto limitado de extensões.

Isso significa que sempre que me deparei com um script de shell no Linux com um shebang para sh:, #!/bin/shmesmo que nessa distribuição, bin/shseja um link simbólico para outro shell, como dash ou bash, ele deve ser 100% compatível com o shell bourne, pois se limita a um conjunto limitado de extensão? Então eu poderia executá-los no FreeBSD? Há exceção a isso? Ou devo estar seguro em assumir que funcionará?

Portanto, se em uma distro, bin/shhouver um link simbólico para bin/bash, e um script usar #!/bin/she o script contiver bashism, ele não será executado, pois o bash gostará do modo sh?

user1115057
fonte

Respostas:

16

Não, se /bin/shum link simbólico para o bash bash entra no modo posix - do man bash :

Quando chamado como sh, o bash entra no modo posix após a leitura dos arquivos de inicialização.

Se você agora procurar o modo posix na página de manual do bash, verá que alguns shell embutidos gostam timeou sourcese comportam de maneira diferente. Isso é tudo. bashishms como escrever functionantes de declarar uma função ou usar em sourcevez de .ainda funcionará, mas os comandos podem se comportar de maneira diferente.

Portanto, se /bin/shum link simbólico para /bin/bashtodos os bashishms típicos ainda funciona.

Para uma lista bastante extensa de diferenças no modo Posix, consulte o manual de referência do bash .

Ulrich Dangel
fonte
Então, acho que a melhor coisa a fazer é testar todos os scripts da ferramenta checkbashism. Ouvi dizer que algumas distros, como o Debian e o Ubuntu (precisam de confirmação para esta), tiveram seu bin / sh agora instável. O traço é compatível com o shell de bico? Se sim, pelo menos todo o script shell Debian e Ubuntu deve estar bem no FreeBSD.
user1115057
@ user1115057 apenas shell scripts com /bin/shcomo shebang. Um script de shell ainda pode usar explicitamente /bin/bash. De qualquer forma, a maioria dos scripts shell provavelmente funcionará bem em / bin / sh, mas o problema serão as ferramentas do usuário, por exemplo, a maioria dos scripts shell espera a área de usuário GNU, o que provavelmente será mais um problema do que apenas um erro de sintaxe. Eu também adicionei um link para a referência do bash que lista o comportamento diferente no modo posix
Ulrich Dangel
Ok, pelo que li, o BSD usa o ash como bin / sh, enquanto o Debian e o Ubuntu usam o traço. Se esses shell forem compatíveis, significa que não haverá mais problemas com o shebang #! / Bin / sh. Mas, como você disse, não haverá outra questão relacionada com a userland ...
user1115057
@ user1115057 traço também não é perfeito, por exemplo wiki.ubuntu.com/DashAsBinSh/#echo scripts de qualquer maneira mais shell são bastante simples e pode ser portado muito facilmente ... boa sorte
Ulrich Dangel
Mas traço e cinzas são compatíveis, certo?
user1115057
8

Parece haver alguma confusão em torno da concha Bourne. O shell Bourne era o shell Unix décadas atrás, nos dias pré-POSIX. Atualmente, "sh" é uma implementação ou outra de um shell que implementa a especificação POSIX, entre as quais temos bash, pdksh, AT&T ksh, novos shell Almquist e seus derivados que foram compatíveis com POSIX (incluindo o "sh" de alguns BSDs). , outros BSDs estão sendo baseados em pdksh e Debian ash (dash)). Até o zsh tem um modo no qual é principalmente compatível com POSIX.

O shell Bourne não é compatível com POSIX e não pode ser encontrado em muitos sistemas atualmente. Onde o shell Bourne é encontrado ou onde não é, sempre haverá um "sh" compatível com POSIX (e não será o shell Bourne), geralmente /binenquanto uma exceção notável (irritante) é o Solaris.

Observe que antes do shell Bourne, e estamos falando há mais de 30 anos, "sh" era o shell Thompson. Não estamos mais escrevendo scripts compatíveis com o shell Thompson. Da mesma forma, devemos parar de pensar em "sh" como a casca de Bourne.

Agora "sh" é uma especificação, não há muitas variantes incompatíveis de uma implementação. Isso facilita muito a gravação de scripts portáteis. Basta seguir a especificação .

Isso vale para "sh" e todos os utilitários padrão (sed, cut, tr ...)

Stéphane Chazelas
fonte
+1 para "gravar na especificação". Mas, infelizmente, isso muitas vezes não é suficiente para portabilidade. Por exemplo, e se alguém quiser usar padrões no estilo egrep no sed? A especificação não prevê isso. Em sistemas com utilitários baseados em Gnu (ou BusyBox), você usa sed -r. Em sistemas com utilitários baseados em BSD, você usa sed -E. O sed do FreeBSD aceita os dois, mas o Mac OS X aceita apenas -E. E assim por diante.
dubiousjim
Isso não vem ao caso. A especificação não a fornece, portanto você não pode usá-la de forma portável / POSIXly. Se você usa BREs, que funcionará em todos os sistemas compatíveis com POSIX, é uma garantia dada pelo POSIX, por isso é útil. Fora do POSIX, como você diz, não há esperança, pois os seds não suportam o ERE ou o suportam com uma opção diferente ou com uma sintaxe diferente do ERE. Observe que os EREs são menos capazes que os BREs (apenas a sintaxe é estendida nos EREs para economizar algumas digitações. Os EREs podem ser traduzidos para BREs, o contrário não é verdadeiro ( \(...\)\1os BREs não têm tradução nos EREs padrão).
Stéphane Chazelas,
1
Percebo que os EREs (POSIX) carecem de referências anteriores; de fato, participei da edição dessa parte do padrão. Não é correto que os EREs POSIX sejam estritamente menos capazes que os BREs, pois no padrão atual, a alternância não é definida para os BREs. No entanto, não conheço nenhum mecanismo de regex que não \|respeite os BREs. Sou a favor de escrever da maneira mais portável possível. Eu estava apenas fazendo a observação (pensei amplamente apreciada) de que isso pode ser doloroso, e às vezes escrever no POSIX simplesmente não é possível. Em algum lugar, existem links que exibem muitas dessas perversões; procurará por eles.
dubiousjim
bom ponto sobre alternância, eu esqueci disso e estou corrigido. Com o sed, é improvável que esteja bloqueando, pois você pode usar várias expressões para corresponder aos regexps alternativos. Existe um problema no baú de ferramentas padrão que pode ser usado se EREs forem necessários. Raramente me encontro no baú de ferramentas padrão e, quando o faço, geralmente são casos em que outra linguagem como perl é mais apropriada, mas entendo seu ponto de vista (embora eu ainda ache que não é o ponto neste tópico sobre como escrever scripts portáteis)
Stéphane Chazelas
Um exemplo que pensei de imediato: as linhas shebang (na parte superior de cada script de shell) não são especificadas no POSIX. Além disso, não sei se já usei um sistema 100% compatível com POSIX. Por exemplo, o POSIX diz que você pode incluir novas linhas dentro, ${VAR:=stuff...here}mas muitas conchas não permitem, você precisa colocar aspas stuff...here.
dubiousjim