Você entendeu ao contrário. /bin/sh
hoje em dia quase nunca é uma concha Bourne, e é quando é que você tem um problema ao usar um #! /bin/sh
estrondo.
O shell Bourne foi um shell escrito no final dos anos 70 e substituiu o shell Thompson anterior (também chamado sh
). No início dos anos 80, David Korn escreveu algumas extensões para o shell Bourne, corrigiu alguns bugs e projetou constrangimentos (e introduziu alguns) e o chamou de shell Korn.
No início dos anos 90, o POSIX especificou o sh
idioma com base em um subconjunto do shell Korn e a maioria dos sistemas agora mudou /bin/sh
para o shell Korn ou um shell compatível com essa especificação. No caso dos BSDs, eles mudaram gradualmente o seu /bin/sh
, inicialmente (depois que não podiam mais usar o shell Bourne por motivos de licença) o shell Almquist, um clone do shell Bourne com algumas extensões ksh para tornar-se compatível com POSIX.
Hoje, todos os sistemas POSIX têm um shell chamado sh
(na maioria das vezes, mas não necessariamente /bin
, o POSIX não especifica o caminho dos utilitários especificados) que é principalmente compatível com POSIX. Geralmente é baseado em ksh88, ksh93, pdksh, bash, ash ou zsh², mas não no shell Bourne, pois o shell Bourne nunca foi compatível com POSIX³. Algumas dessas conchas ( bash
, zsh
, yash
e alguns pdksh
derivados de permitir um modo compatível com POSIX quando invocada como sh
e são menos compatíveis em contrário).
bash
(a resposta da GNU para o shell Korn) é na verdade o único shell de código aberto (e pode-se dizer que atualmente é mantido, pois os outros geralmente são baseados no ksh88, que não recebeu nenhum novo recurso desde os anos 90) que foi certificado como sendo compatível com POSIX sh
(como parte da certificação macOS).
Quando você escreve um script com um #! /bin/sh -
she-bang, deve usar uma sh
sintaxe padrão (e também deve usar a sintaxe padrão para os utilitários usados nesse script, se quiser ser portátil, não é apenas o shell que está envolvido na interpretação de um shell script), então não importa qual implementação desse sh
interpretador de sintaxe padrão seja usada ( ksh
, bash
...).
Não importa que essas cascas tenham extensões acima do padrão, desde que você não as utilize. É como escrever código C, desde que você escreva código C padrão e não use extensões de um compilador (como gcc
) ou outro, seu código deve compilar OK, independentemente da implementação do compilador, desde que o compilador seja compatível.
Aqui, com o seu #! /bin/sh
she-bang, o seu principal problema seria os sistemas onde /bin/sh
é o shell Bourne que, por exemplo, não suporta características padrão, como $((1+1))
, $(cmd)
, ${var#pattern}
... Em que caso você pode precisar de soluções alternativas como:
#! /bin/sh -
if false ^ true; then
# in the Bourne shell, ^ is an alias for |, so false ^ true returns
# true in the Bourne shell and the Bourne shell only.
# Assume the system is Solaris 10 (older versions are no longer maintained)
# You would need to adapt if you need to support some other system
# where /bin/sh is the Bourne shell.
# We also need to fix $PATH as the other utilities in /bin are
# also ancient and not POSIX compatible.
PATH=`/usr/xpg6/bin/getconf PATH`${PATH:+:}$PATH || exit
export PATH
exec /usr/xpg4/bin/sh "$0" "$@"
# that should give us an environment that is mostly compliant
# to the Single UNIX Specification version 3 (POSIX.2004), the
# latest supported by Solaris 10.
fi
# rest of the script
A propósito, o Ubuntu /bin/sh
não é bash
por padrão. Hoje em dash
dia, um shell baseado no NetBSD sh
, ele próprio baseado no shell Almquist, que é principalmente compatível com POSIX, exceto que ele não suporta caracteres de vários bytes. Em outros sistemas baseados em Debian Ubuntu e, você pode escolher entre bash
e dash
para /bin/sh
com dpkg-reconfigure dash
) 4 . sh
Os scripts enviados com o Debian devem funcionar da mesma forma nos dois shells, à medida que são gravados no padrão de política Debian (um superconjunto do padrão POSIX). Você provavelmente vai descobrir que eles também trabalho OK em zsh
's sh
emulação ou bosh
(provavelmente não ksh93
, nem yash
que não tem um local
builtin (exigido pela política Debian, mas não POSIX)).
Todos os sistemas no escopo em unix.stackexchange.com possuem um POSIX em sh
algum lugar. A maioria deles possui um /bin/sh
(você pode encontrar outros muito raros que não têm um /bin
diretório, mas provavelmente não se importa com isso), e isso geralmente é um sh
interpretador POSIX (e, em casos raros, um shell Bourne (não padrão) )
Mas sh
é o único executável de interpretador de shell que você pode encontrar em um sistema. Para os outros shells, você pode ter certeza de que o macOS, Cygwin e a maioria das distribuições GNU / Linux terão bash
. Os sistemas operacionais derivados do SYSV (Solaris, AIX ...) geralmente terão o ksh88, possivelmente o ksh93. O OpenBSD, MirOS, terá um derivado pdksh. o macOS terá zsh
. Mas fora disso, não haverá garantia. Não há garantia de que um bash
ou outro desses shells será instalado em /bin
ou em outro local (geralmente é encontrado nos /usr/local/bin
BSDs quando instalados, por exemplo). E, claro, nenhuma garantia da versão do shell que será instalada.
Observe que o #! /path/to/executable
não é uma convenção , é um recurso de todos os kernels do tipo Unix ( introduzidos no início dos anos 80 por Dennis Ritchie ) que permite executar arquivos arbitrários, especificando o caminho do intérprete na primeira linha, começando com #!
. Pode ser qualquer executável.
Quando você executa um arquivo cuja primeira linha começa com #! /some/file some-optional-arg
, o kernel acaba executando/some/file
com some-optional-arg
, o caminho do script e os argumentos originais como argumentos. Você pode fazer essa primeira linha #! /bin/echo test
para ver o que está acontecendo:
$ ./myscript foo
test ./myscript foo
Quando você usa em /bin/sh -
vez de /bin/echo test
, o kernel executa/bin/sh - ./myscript foo
, sh
interpreta o código de conteúdo armazenado myscript
e ignora a primeira linha como um comentário (começa com #
).
¹ Provavelmente, o único sistema hoje em que algum de nós se depara com um /bin/sh
baseado no shell Bourne é o Solaris 10. O Solaris é um dos poucos Unices que decidiu manter um shell Bourne lá para compatibilidade com versões anteriores (o POSIXsh
linguagem não é totalmente compatível com versões anteriores do shell Bourne) e (pelo menos para implantações de desktop e servidor completo) têm o POSIX em sh
outro lugar (em /usr/xpg4/bin/sh
, com base no ksh88), mas isso mudou no Solaris 11, onde /bin/sh
agora é o ksh93. Os outros são quase extintos.
² O /bin/sh
MacOS / X costumava serzsh
, mas depois mudou para bash
. Não é zsh
o foco principal a ser usado como uma sh
implementação POSIX . Seu sh
modo é principalmente poder incorporar ou chamar o código source
POSIX ( ) sh
nos zsh
scripts
³ Recentemente, a @schily estendeu o shell do OpenSolaris (base no shell do SVR4, baseado no shell Bourne) para se tornar compatível com POSIX, chamado, bosh
mas não sei que ele ainda é usado em qualquer sistema. Junto com ksh88
isso, é um segundo shell compatível com POSIX, com base no código do shell Bourne
4 Nas versões mais antigas, você também pode usar mksh
ou sua lksh
encarnação mais POSIX . Esse é o shell do MirOS (anteriormente MirBSD) baseado no pdksh, baseado no shell Forsyth (outra reimplementação do shell Bourne))