Eu vi a frase "compatível com sh" usada geralmente em referência a conchas. Não tenho certeza se isso também se aplica aos programas que podem ser executados a partir de shells.
O que significa um shell ou outro programa ser "compatível com sh"? O que significaria ser "sh incompatible"?
Edit: Esta pergunta que faz a diferença entre bash e sh é muito relevante: Diferença entre sh e bash
Eu ainda gostaria de uma resposta direta ao que significa ser "sh compatível". Uma expectativa razoável pode ser que "sh compatível" signifique "implementa a linguagem de comando do shell", mas por que existem tantos shells "compatíveis com sh" e por que são diferentes?
shell
compatibility
Praxeolitic
fonte
fonte
sh
). Para um shell diferente, refere-se à possibilidade de executar ou não scripts de shell Bourne.Respostas:
O shell Bourne foi lançado pela primeira vez em 1979 como parte do Unix V7 . Como praticamente todos os sistemas Unix e similares ao Unix descendem do V7 Unix - mesmo que apenas espiritualmente -, o shell Bourne está conosco "para sempre".
O shell Bourne, na verdade, substituiu um shell anterior, retronomeou o shell Thompson , mas aconteceu tão cedo na história do Unix que hoje está praticamente esquecido. A concha Bourne é um superconjunto da concha Thompson .²
Ambos os cartuchos de Bourne e Thompson foram chamados
sh
. O shell especificado pelo POSIX também é chamadosh
. Então, quando alguém diz que ésh
compatível, está se referindo a essa série de cartuchos. Se eles quisessem ser específicos, diriam "shell POSIX" ou "shell Bourne". ³O shell POSIX é baseado na versão de 1988, KornShell , que por sua vez foi concebido para substituir o shell Bourne no AT & T Unix, ultrapassando o shell C BSD em termos de features.⁴ Na medida em que
ksh
é o antepassado do shell POSIX, a maioria Os sistemas Unix e Unix-like incluem algumas variantes do shell Korn atualmente. As exceções são geralmente pequenos sistemas embarcados, que não podem permitir o espaço que um shell POSIX completo ocupa.Dito isto, o shell Korn - como algo distinto do shell POSIX - nunca se tornou realmente popular fora do mundo comercial do Unix. Isso ocorre porque seu crescimento correspondeu aos primeiros anos de comercialização do Unix, por isso foi pego nas guerras do Unix . O BSD Unixes o evitou em favor do shell C, e seu código-fonte não estava disponível gratuitamente para uso no Linux quando foi iniciado.⁵ Então, quando os primeiros distribuidores do Linux procuraram um shell de comando para acompanhar seu kernel Linux, eles geralmente escolhem o GNU Bash , um dos
sh
compatíveis de que você está falando.⁶Essa associação inicial entre Linux e Bash praticamente selou o destino de muitos outros shells, incluindo
ksh
,csh
etcsh
. Ainda existem pessoas obstinadas que usam essas conchas hoje em dia, mas são muito minoritárias.Toda essa história explica por que os criadores de retardatários relativos gostam de
bash
,zsh
eyash
optaram por torná-lossh
compatíveis: a compatibilidade com Bourne / POSIX é o mínimo que um shell para sistemas semelhantes a Unix deve fornecer para obter ampla adoção.Em muitos sistemas, o shell de comando interativo padrão e
/bin/sh
são coisas diferentes./bin/sh
talvez:O shell Bourne original. Isso é comum em sistemas UNIX® mais antigos, como o Solaris 10 (lançado em 2005) e seus antecessores.⁸
Um shell certificado pelo POSIX. Isso é comum em sistemas UNIX® mais recentes, como o Solaris 11 (2010).
A concha Almquist . Este é um clone de shell de código aberto Bourne / POSIX lançado originalmente na Usenet em 1989 , que depois contribuiu com o CSRG de Berkeley para inclusão na primeira versão do BSD que não contém código-fonte da AT&T, 4.4BSD-Lite . O shell Almquist é chamado frequentemente
ash
, mesmo quando instalado como/bin/sh
.O 4.4BSD-Lite, por sua vez, tornou-se a base para todos os derivados modernos do BSD,
/bin/sh
permanecendo como um derivado Almquist na maioria deles, com uma grande exceção observada abaixo. Você pode ver essa descendência direta nos repositórios de código-fonte do NetBSD e FreeBSD : eles estavam enviando um derivado do shell Almquist desde o primeiro dia.Existem dois
ash
garfos importantes fora do mundo do BSD:dash
, adotado pelo Debian e Ubuntu em 2006 como a/bin/sh
implementação padrão . (O Bash continua sendo o shell de comando interativo padrão nos derivados do Debian.)O
ash
comando no BusyBox , que é freqüentemente usado em Linuxs embarcados e pode ser usado para implementar/bin/sh
. Desde que ele é pós-datadodash
e foi derivado doash
pacote antigo do Debian , eu escolhi considerá-lo um derivado de,dash
e nãoash
, apesar do nome do comando no BusyBox.(O BusyBox também inclui uma alternativa menos funcional ao
ash
chamadohush
. Normalmente, apenas um dos dois será incorporado a qualquer dado binário do BusyBox:ash
por padrão, mashush
quando o espaço é muito/bin/sh
pequeno . Assim, em sistemas baseados no BusyBox nem sempre édash
parecido.)GNU Bash , que desativa a maioria de suas extensões não POSIX quando chamado como
sh
.Essa escolha é típica nas variantes de desktop e servidor do Linux, exceto o Debian e seus derivados. O Mac OS X também faz isso desde o Panther, lançado em 2003.
Um shell com
ksh93
extensões POSIX , como no OpenBSD . Embora o shell do OpenBSD mude o comportamento para evitar incompatibilidades de sintaxe e semântica com os shells Bourne e POSIX quando chamadosh
, ele não desabilita nenhuma de suas extensões puras, sendo aquelas que não conflitam com os shells mais antigos.Isso não é comum; você não deve esperar
ksh93
recursos/bin/sh
.Eu usei "shell script" acima como um termo genérico que significa script de shell Bourne / POSIX. Isso se deve à onipresença das conchas da família Bourne. Para falar sobre scripts em outros shells, você precisa fornecer um qualificador, como "C shell script". Mesmo nos sistemas em que um shell da família C é o shell interativo padrão, é melhor usar o shell Bourne para scripts.
É revelador que quando a Wikipedia classifica os shells do Unix , eles os agrupam em Bourne shell compatível, C shell compatível e "outros".
Este diagrama pode ajudar:
(Clique para a versão SVG, 31 kB, ou para ver a versão PNG em tamanho real , 218 kB.)
Alguém falando sobre
sh
algo incompatível normalmente significa uma das três coisas:Eles estão se referindo a um desses "outros" shells.⁹
Eles estão fazendo uma distinção entre as famílias Bourne e C shell.
Eles estão falando sobre algum recurso específico em uma concha da família Bourne que não está em todas as outras conchas da família Bourne.
ksh93
,,bash
ezsh
em particular, têm muitos recursos que não existem nos shells "padrão" mais antigos. Esses três também são incompatíveis entre si de várias maneiras, depois que você ultrapassa o POSIX /ksh88
base compartilhado .É um erro clássico escrever um script de shell com uma
#!/bin/sh
linha shebang na parte superior, mas usar as extensões de shell Bash ou Korn. Como/bin/sh
é um dos shells no diagrama da família Korn / POSIX acima em muitos sistemas hoje em dia, esses scripts funcionarão no sistema em que estão escritos, mas depois falharão nos sistemas, onde/bin/sh
é algo da família de shells Bourne mais ampla. A melhor prática é usar#!/bin/bash
ou#!/bin/ksh
mostrar linhas se o script usar essas extensões.Existem várias maneiras de verificar se um determinado script do shell da família Bourne é portátil:
Execute
checkbashisms
nele, uma ferramenta do projeto Debian que verifica um script em busca de " basismos ".Execute-o em
posh
um shell no repositório de pacotes Debian que propositalmente implementa apenas os recursos especificados pelo SUS3 , além de alguns outros recursos menores .Executá-lo sob
osh
a partir do projeto Ferramentas Schily , uma versão melhorada do Bourne shell como software livre pela Sun como parte do OpenSolaris em 2005, tornando-se uma das maneiras mais fáceis de obter um estilo de 1979 Bourne shell em um computador moderno.A distribuição do Schily Tools também inclui
bosh
um shell do tipo POSIX com muitos recursos fora do padrão , mas que pode ser útil para testar a compatibilidade de scripts de shell destinados a serem executados em todos os shells da família POSIX. Ele tende a ser mais conservadora no seu conjunto de recursos debash
,zsh
e as versões melhoradas dosksh93
.O Schily Tools também inclui um shell chamado
bsh
, mas essa é uma singularidade histórica que não é um shell da família Bourne.Veja o capítulo sobre programação portátil do shell no manual GNU Autoconf . Você pode reconhecer algumas das construções problemáticas mencionadas em seus scripts.
Pelas mesmas razões, todos os "Novos e aprimorados!" as coisas são diferentes:
A versão aprimorada só poderia ser aprimorada quebrando a compatibilidade com versões anteriores.
Alguém pensou em uma maneira diferente de algo funcionar, do que eles gostam mais, mas que não é da mesma maneira que o antigo funcionava.
Alguém tentou reimplementar um padrão antigo sem entendê-lo completamente, por isso estragou tudo e criou uma diferença não intencional.
Notas de rodapé e apartes :
As primeiras versões do BSD Unix eram apenas coleções de software complementares para o V6 Unix. Como o shell Bourne não foi adicionado ao AT&T Unix até a V7, o BSD tecnicamente não começou com o shell Bourne. A resposta de BSD à natureza primitiva do shell Thompson foi o shell C .
No entanto, as primeiras versões independentes de BSD (2.9BSD e 3BSD) foram baseadas em V7 ou seu sucessor portátil UNIX / 32V , então eles fizeram incluir o shell Bourne.
(A linha 2BSD se transformou em um garfo paralelo de BSD para da Digital minicomputadores PDP , enquanto as linhas 3BSD e 4BSD passou a tirar proveito de tipos de computadores mais recentes, como Vaxen e estações de trabalho UNIX 2.9BSD era essencialmente a versão PDP de 4.1cBSD;. Fossem contemporânea, e código compartilhado . PDPs não simplesmente desaparecer quando o VAX chegou, para que a linha 2BSD é ainda bamboleando ao longo ).
É seguro dizer que o shell Bourne estava presente em todo o mundo Unix em 1983. Essa é uma boa aproximação de "para sempre" na indústria de computação. O MS-DOS obteve um sistema de arquivos hierárquico naquele ano (awww, que delícia!) E o primeiro Macintosh de 24 bits com sua tela de 9 "em preto e branco - não em escala de cinza, literalmente em preto e branco - não seria lançado até o início do próximo ano.
O shell Thompson era bastante primitivo para os padrões de hoje. Era apenas um shell de comando interativo, em vez do ambiente de programação de scripts que esperamos hoje. Ele tinha coisas como pipes e redirecionamento de E / S, que consideramos prototipicamente parte de um "shell Unix", de modo que pensamos no shell de comando do MS-DOS como obtê-los do Unix.
O shell Bourne também substituiu o shell PWB , que adicionou coisas importantes ao shell Thompson, como programabilidade (
if
,switch
ewhile
) e uma forma inicial de variáveis de ambiente. O shell PWB é ainda menos lembrado que o shell Thompson, pois não fazia parte de todas as versões do Unix.Quando alguém não é específico sobre a compatibilidade de shell POSIX x Bourne, há várias coisas que eles podem significar.
Em um extremo, eles poderiam estar usando o shell Bourne de 1979 como linha de base. Um "
sh
roteiro -compatível" neste sentido significaria espera-se para executar perfeitamente no shell Bourne verdadeira ou qualquer dos seus sucessores e clones:ash
,bash
,ksh
,zsh
, etc.Alguém no outro extremo assume o shell especificado pelo POSIX como uma linha de base. Tomamos tantos recursos do shell POSIX como "padrão" hoje em dia que muitas vezes esquecemos que eles não estavam realmente presentes no shell Bourne: aritmética integrada, controle de tarefas, histórico de comandos, aliases, edição de linha de comando, a
$()
forma de comando substituição etc.Embora o shell Korn tenha raízes desde o início dos anos 80, a AT&T não o lançou no Unix até o System V, versão 4, em 1988. Como muitos Unixes comerciais são baseados no SVR4, isso inclui
ksh
praticamente todos os Unix comerciais relevantes do final dos anos 80 em diante.(Alguns sabores estranhos do Unix baseados em SVR3 e anteriores mantiveram partes do mercado após o lançamento do SVR4, mas foram os primeiros contra a parede quando a revolução veio).
1988 é também o ano em que o primeiro padrão POSIX foi lançado, com seu "POSIX shell" baseado em shell Korn. Mais tarde, em 1993, uma versão aprimorada do shell Korn foi lançada. Desde que o POSIX efetivamente pregou o original, foi
ksh
dividido em duas versões principais:ksh88
eksh93
, nomeado após os anos envolvidos em sua divisão.ksh88
não é totalmente compatível com POSIX, embora as diferenças sejam pequenas, de modo que algumas versões doksh88
shell foram corrigidas para serem compatíveis com POSIX. (Isso de uma interessante entrevista no Slashdot com o Dr. David G. Korn . Sim, o cara que escreveu o shell.)ksh93
é um superconjunto totalmente compatível do shell POSIX . O desenvolvimentoksh93
foi esporádico desde que o repositório de origem primário foi transferido da AT&T para o GitHub, com a versão mais recente com cerca de 3 anos de idade, enquanto escrevo isso, ksh93v. (O nome base do projeto permaneceksh93
com sufixos adicionados para indicar versões de lançamento além de 1993.)Os sistemas que incluem um shell Korn como algo separado do shell POSIX geralmente o tornam disponível
/bin/ksh
, embora às vezes ele esteja oculto em outro lugar.Quando falamos sobre
ksh
ou o shell Korn por nome, estamos falando deksh93
recursos que o distinguem de seus subconjuntos de shell Bourne e POSIX compatíveis com versões anteriores. Você raramente encontra os purosksh88
hoje.A AT&T manteve o código-fonte do shell Korn como proprietário até março de 2000 . Nesse ponto, a associação do Linux ao GNU Bash era muito forte. O Bash e
ksh93
cada um têm vantagens em relação ao outro , mas, neste momento, a inércia mantém o Linux fortemente associado ao Bash.Quanto ao motivo pelo qual os primeiros fornecedores de Linux costumam escolher o GNU Bash
pdksh
, que estava disponível no momento em que o Linux era iniciado, eu acho que é porque grande parte do restante da área de usuários também veio do projeto GNU . O Bash também é um pouco mais avançado quepdksh
, já que os desenvolvedores do Bash não se limitam a copiar os recursos do shell Korn.O trabalho
pdksh
parou no momento em que a AT&T lançou o código-fonte para o verdadeiro shell Korn. Existem dois garfos principais que ainda são mantidos: o OpenBSDpdksh
eo MirBSD Korn Shellmksh
,.Acho interessante que
mksh
seja a única implementação de shell Korn atualmente empacotada para Cygwin.O GNU Bash vai além do POSIX de várias maneiras, mas você pode solicitar que ele execute em um modo POSIX mais puro .
csh
/tcsh
era geralmente o shell interativo padrão no BSD Unixes até o início dos anos 90.Por ser uma variante BSD , as versões anteriores do Mac OS X eram assim, através do Mac OS X 10.2 "Jaguar" . O OS X mudou o shell padrão
tcsh
para o Bash no OS X 10.3 "Panther" . Essa alteração não afetou os sistemas atualizados da versão 10.2 ou anterior. Os usuários existentes nesses sistemas convertidos mantiveram seutcsh
shell.O FreeBSD afirma ainda usar
tcsh
como shell padrão , mas na VM do FreeBSD 10 que tenho aqui, o shell padrão parece ser uma das variantes de shell Almquist compatíveis com POSIX . Isso também é verdade no NetBSD.O OpenBSD usa uma bifurcação
pdksh
como shell padrão.A maior popularidade do Linux e do OS X faz com que algumas pessoas desejem que o FreeBSD também mude para o Bash, mas não o farão tão cedo por razões filosóficas . É fácil trocá-lo , se isso o incomoda.
É raro encontrar um sistema com uma casca Bourne verdadeiramente baunilha
/bin/sh
nos dias de hoje. Você precisa fazer o possível para encontrar algo suficientemente próximo para testar a compatibilidade.Estou ciente de apenas uma maneira de executar um shell Bourne vintage genuíno de 1979 em um computador moderno: use as imagens de disco do Ancient Unix V7 com o simulador SIMH PDP-11 do Computer History Simulation Project . O SIMH roda em praticamente todos os computadores modernos , não apenas no Unix. O SIMH ainda roda no Android e no iOS .
Com o OpenSolaris , a Sun forneceu pela primeira vez a versão SVR4 do shell Bourne. Antes disso, o código-fonte das versões pós-V7 do shell Bourne estava disponível apenas para aqueles com uma licença de código-fonte Unix.
Agora esse código está disponível separadamente do restante do projeto OpenSolaris extinto, de várias fontes diferentes.
A fonte mais direta é o projeto de shell Heirloom Bourne . Isso ficou disponível logo após o lançamento original do OpenSolaris em 2005. Alguns trabalhos de portabilidade e correção de bugs foram realizados nos próximos meses, mas o desenvolvimento do projeto foi interrompido.
Jörg Schilling fez um trabalho melhor em manter uma versão desse código como
osh
em seu pacote Schily Tools . Veja acima para mais informações.Lembre-se de que esses shells derivados da versão de código-fonte de 2005 contêm suporte a conjuntos de caracteres de vários bytes , controle de tarefas, funções de shell e outros recursos não presentes no shell Bourne original de 1979.
Uma maneira de saber se você está em um shell Bourne original é verificar se ele suporta um recurso não documentado adicionado para facilitar a transição do shell Thompson:
^
como um alias para|
. Ou seja, um comando comols ^ more
dará um erro em um shell do tipo Korn ou POSIX, mas se comportará comols | more
em um shell Bourne verdadeiro.Ocasionalmente, você encontra um
fish
,scsh
ourc/es
aderente, mas eles são ainda mais raros do que os ventiladores C shell.A
rc
família de shells não é comumente usada em sistemas Unix / Linux, mas a família é historicamente importante, e foi assim que ganhou um lugar no diagrama acima.rc
é o shell padrão do Plan 9 do sistema operacional Bell Labs , um tipo de sucessor da 10ª edição do Unix , criado como parte da pesquisa contínua da Bell Labs em design de sistema operacional. É incompatível com os shell Bourne e C em um nível de programação; provavelmente há uma lição lá.A variante mais ativa
rc
parece ser a mantida por Toby Goodwin , que é baseada norc
clone Unix de Byron Rakitzis.fonte
"sh compatible" refere-se ao POSIX
sh
, o shell básico necessário para existir em todos os sistemas compatíveis. Um script compatível com sh deve funcionar em qualquer máquina compatível com POSIX.A razão é necessário dizê-lo é que geralmente
/bin/sh
é um link simbólico para/bin/bash
, que deixou algumas Bashisms escorregar em scripts que se declaram usarsh
com#!/bin/sh
. Esses scripts não funcionam em sistemas que não usambash
como/bin/sh
, incluindo alguns Unices comerciais para sempre, e Debian e derivados recentemente.Em particular, tem havido uma tendência a usar
dash
, o Debian Almquish Shell, como o padrãosh
ultimamente, porque é menor e deve ser mais rápido. Essa tendência destacou muitos desses bashismos que estavam em supostossh
scripts. A descrição de algo como "compatível com sh" indica que se destina explicitamente a trabalhar com esses sistemas, mantendo-se inteiramente dentro da linguagem especificada no POSIX - todos os shells implementarão um superconjunto dessa funcionalidade, garantindo que funcione em qualquer lugar, mas suas extensões não são compatível um com o outro.Os shells diferentes têm seu próprio histórico de desenvolvimento e divergem em diferentes direções ao longo do tempo, à medida que adicionam funções para ajudar o uso interativo de seus usuários ou extensões de script como matrizes associativas. Um script "incompatível com sh" usaria alguns desses recursos de extensão não padrão, como os
[[
condicionais de Bash .Os recursos não-POSIX em
bash
etcsh
ezsh
todos os outros shells atuais são úteis , e há muitas ocasiões em que você pode querer ou precisar deles. Eles simplesmente não devem ser usados em um script que se declara trabalhar/bin/sh
, porque você não pode confiar nesses recursos nash
implementação básica no sistema em que está executando.Um script que precisa usar, por exemplo, matrizes associativas, deve garantir que seja executado com
bash
e nãosh
:Isso funcionará em qualquer lugar
bash
. Os scripts que não precisam da funcionalidade estendida e devem ser portáveis devem declarar que usamsh
e mantêm a linguagem de comando do shell base.fonte