Che cosa significa essere "sh compatibile"?


63

Ho visto la frase "sh compatibile" usata di solito in riferimento alle shell. Non sono sicuro che si applichi anche ai programmi che potrebbero essere eseguiti all'interno delle shell.

Cosa significa che una shell o un altro programma è "sh compatibile"? Cosa significherebbe essere "sh incompatibile"?

Modifica: questa domanda che pone la differenza tra bash e sh è molto rilevante: differenza tra sh e bash

Vorrei ancora una risposta diretta a cosa significhi essere "sh compatibile". Un'aspettativa ragionevole potrebbe essere che "sh compatibile" significa "implementa il linguaggio di comando Shell", ma allora perché ci sono così tante shell "sh compatibili" e perché sono diverse?


1
Per uno script di shell, si riferisce al fatto che lo script utilizzi o meno la sintassi compatibile (eseguibile) con Bourne Shell ( sh). Per una shell diversa, indica se quella shell può eseguire o meno gli script della shell Bourne.
HalosGhost,

Se vuoi imparare l'inventore delle conchiglie puoi visitare la mia risposta su unix.stackexchange.com/questions/45684/…
PersianGulf

Risposte:


116

Perché ci sono così tante shell "sh compatibili"?

La shell Bourne fu rilasciata pubblicamente nel 1979 come parte di Unix V7 . Poiché praticamente ogni sistema Unix e Unix discende da V7 Unix - anche se solo spiritualmente - la shell Bourne è stata con noi "per sempre". ¹

La shell Bourne in realtà ha sostituito una shell precedente, ha rinominato la shell Thompson , ma è accaduto così presto nella storia di Unix che oggi è quasi dimenticato. La shell Bourne è un superset della shell Thompson

Furono chiamati sia i gusci Bourne che Thompson sh. La shell specificato da POSIX è anche chiamato sh. Quindi, quando qualcuno dice sh-compatibile, si riferiscono a mano a questa serie di conchiglie. Se volessero essere specifici, direbbero "shell POSIX" o "shell Bourne". ³

La shell POSIX si basa sulla versione 1988 di KornShell , che a sua volta doveva sostituire la shell Bourne su AT&T Unix, saltando la shell BSD C in termini di funzionalità. ⁴ Nella misura in cui kshè l'antenata della shell POSIX, la maggior parte I sistemi Unix e Unix includono oggi alcune varianti della shell Korn. Le eccezioni sono generalmente piccoli sistemi embedded, che non possono permettersi lo spazio che occupa una shell POSIX completa.

Detto questo, la shell Korn - come una cosa distinta dalla shell POSIX - non è mai diventata molto popolare al di fuori del mondo commerciale di Unix. Questo perché la sua ascesa corrispondeva ai primi anni della commercializzazione di Unix, quindi fu coinvolto nelle guerre di Unix . BSD Unixes lo ha eluso a favore della shell C, e il suo codice sorgente non è stato liberamente disponibile per l'uso in Linux quando è stato avviato. »Quindi, quando i primi distributori di Linux sono andati alla ricerca di una shell di comando da utilizzare con il loro kernel Linux, di solito hanno scelto GNU Bash , uno di quelli di shcui stai parlando. ⁶

Che presto associazione tra Linux e bash praticamente sigillato il destino di molte altre shell, tra cui ksh, cshe tcsh. Ci sono ancora degli irriducibili che usano ancora quelle conchiglie oggi, ma sono molto in minoranza

Tutta questa storia spiega perché i creatori di ritardatari relativi come bash, zsh, e yashscelto per renderli shcompatibile: Bourne compatibilità / POSIX è il minimo una shell per sistemi tipo Unix deve fornire al fine di ottenere l'adozione diffusa.

In molti sistemi, la shell dei comandi interattiva predefinita e /bin/shsono cose diverse. /bin/shpuò essere:

  • La shell Bourne originale. Questo è comune nei vecchi sistemi UNIX®, come Solaris 10 (rilasciato nel 2005) e i suoi predecessori. ⁸

  • Una shell certificata POSIX. Questo è comune nei nuovi sistemi UNIX®, come Solaris 11 (2010).

  • Il guscio di Almquist . Questo è un clone di shell Bourne / POSIX open source originariamente rilasciato su Usenet nel 1989 , che è stato poi contribuito al CSRG di Berkeley per l'inclusione nella prima versione BSD che non contiene codice sorgente AT&T, 4.4BSD-Lite . La shell Almquist viene spesso chiamata ash, anche se installata come /bin/sh.

    4.4BSD-Lite a sua volta divenne la base per tutti i derivati ​​BSD moderni, /bin/shrimanendo come un derivato Almquist nella maggior parte di essi, con una delle principali eccezioni indicate di seguito. Puoi vedere questa diretta discendenza nei repository del codice sorgente per NetBSD e FreeBSD : stavano spedendo un derivato della shell Almquist dal primo giorno.

    Esistono due ashforcelle importanti al di fuori del mondo BSD:

    1. dash, notoriamente adottato da Debian e Ubuntu nel 2006 come /bin/shimplementazione predefinita . (Bash rimane la shell dei comandi interattiva predefinita nei derivati ​​Debian.)

    2. Il ashcomando in BusyBox , che viene spesso utilizzato in Linux integrati e può essere utilizzato per l'implementazione /bin/sh. Dal momento che postdatizza dashed è stato derivato dal vecchio ashpacchetto di Debian , ho scelto di considerarlo un derivato dashpiuttosto che ash, nonostante il suo nome di comando all'interno di BusyBox.

      (BusyBox include anche un'alternativa meno caratteristica al ashrichiamo hush. In genere solo uno dei due verrà incorporato in un dato binario BusyBox: ashper impostazione predefinita, ma hushquando lo spazio è molto ridotto. Pertanto, /bin/shsui sistemi basati su BusyBox non è sempre dashsimile.)

  • GNU Bash , che disabilita la maggior parte delle sue estensioni non POSIX quando viene chiamato comesh .

    Questa scelta è tipica nelle varianti desktop e server di Linux, ad eccezione di Debian e dei suoi derivati. Mac OS X lo ha fatto anche da Panther, rilasciato nel 2003.

  • Una shell con ksh93estensioni POSIX , come in OpenBSD . Sebbene la shell OpenBSD cambi il comportamento per evitare sintassi e incompatibilità semantiche con le shell Bourne e POSIX quando chiamate come sh, non disabilita nessuna delle sue estensioni pure, essendo quelle che non sono in conflitto con le shell più vecchie.

    Questo non è comune; non dovresti aspettarti ksh93funzionalità in /bin/sh.

Ho usato "shell script" sopra come un termine generico che significa script di shell Bourne / POSIX. Ciò è dovuto all'ubiquità delle conchiglie della famiglia Bourne. Per parlare di scripting su altre shell, è necessario fornire un qualificatore, come "Script shell C." Anche su sistemi in cui una shell della famiglia C è la shell interattiva predefinita, è meglio usare la shell Bourne per gli script.

Sta dicendo che quando Wikipedia classifica le shell Unix , le raggruppano in Bourne shell compatibile, C shell compatibile e "altro".

Questo diagramma può aiutare:

Le conchiglie Unix: famiglie di shell Bourne, Korn, POSIX, C e rc

(Fare clic per la versione SVG, 31 kB o visualizzare la versione PNG full-size , 218 kB.)

Cosa significherebbe essere "sh incompatibile"?

Qualcuno che parla di una shcosa incompatibile in genere significa una delle tre cose:

  1. Si riferiscono a una di quelle "altre" conchiglie⁹

  2. Stanno facendo una distinzione tra le famiglie di conchiglie Bourne e C.

  3. Stanno parlando di alcune caratteristiche specifiche in una shell della famiglia Bourne che non è presente in tutte le altre shell della famiglia Bourne. ksh93, bashe zshin particolare hanno molte caratteristiche che non esistono nelle vecchie shell "standard". Questi tre sono anche reciprocamente incompatibili in molti modi, una volta che si supera il POSIX / ksh88base condivisa .

È un classico errore scrivere uno script di shell con una #!/bin/sh riga shebang in alto ma usare all'interno delle estensioni della shell Bash o Korn. Dal momento che /bin/shè una delle shell nel diagramma della famiglia Korn / POSIX sopra su così tanti sistemi in questi giorni, tali script funzioneranno sul sistema su cui sono scritti, ma poi falliranno su sistemi in cui /bin/shc'è qualcosa della più ampia famiglia di shell Bourne. Le migliori pratiche è quello di utilizzare #!/bin/basho #!/bin/kshfaccenda righe se lo script utilizza tali estensioni.

Esistono molti modi per verificare se un determinato script della shell della famiglia Bourne è portatile:

  • Esegui checkbashismssu di esso, uno strumento del progetto Debian che controlla uno script per " bashismi ".

  • Eseguilo sotto posh, una shell nel repository di pacchetti Debian che implementa di proposito solo le funzionalità specificate da SUS3 , oltre ad alcune altre funzionalità minori .

  • Eseguire sotto oshdal progetto Strumenti Schily , una versione migliorata del Bourne shell come open source da Sun come parte di OpenSolaris nel 2005, che lo rende uno dei modi più semplici per ottenere uno stile di 1979 Bourne shell su un computer moderno.

    La distribuzione di Schily Tools include anche boshuna shell di tipo POSIX con molte funzionalità non standard , ma che può essere utile per testare la compatibilità degli script di shell destinati a essere eseguiti su tutte le shell della famiglia POSIX. Si tende ad essere più prudenti nel suo set di funzionalità rispetto bash, zshe le versioni migliorate di ksh93.

    Schily Tools include anche una shell chiamata bsh, ma questa è una stranezza storica che non è affatto una shell della famiglia Bourne.

  • Passare attraverso il capitolo Programmazione della shell portatile nel manuale GNU Autoconf . Potresti riconoscere alcuni dei costrutti problematici di cui parla nei tuoi script.

Perché sono diversi?

Per gli stessi motivi, tutto "Nuovo e migliorato!" le cose sono diverse:

  • La versione migliorata potrebbe essere migliorata solo rompendo la compatibilità all'indietro.

  • Qualcuno ha pensato a un modo diverso per far funzionare qualcosa, che a loro piace di più, ma che non è allo stesso modo di quello vecchio.

  • Qualcuno ha provato a reimplementare un vecchio standard senza comprenderlo completamente, quindi hanno incasinato e creato una differenza involontaria.


Note a piè di pagina e oltre :

  1. Le prime versioni di BSD Unix erano solo raccolte di componenti aggiuntivi per V6 Unix. Poiché la shell Bourne non è stata aggiunta a Unix AT&T fino alla V7, BSD non ha tecnicamente iniziato con la shell Bourne. La risposta di BSD alla natura primitiva del guscio Thompson era la shell C .

    Tuttavia, le prime versioni autonome di BSD (2.9BSD e 3BSD) erano basate su V7 o il suo successore portatile UNIX / 32V , in modo che ha fatto includere la shell Bourne.

    (La linea 2BSD si è trasformata in un fork parallelo di BSD per i minicomputer PDP di Digital , mentre le linee 3BSD e 4BSD hanno continuato a sfruttare i più recenti tipi di computer come le workstation Vaxen e Unix . 2.9BSD era essenzialmente la versione PDP di 4.1cBSD; erano contemporanea, e il codice condiviso . PDP non solo scompaiono quando il VAX arrivati, quindi la linea 2BSD è ancora Shambling lungo .)

    È sicuro dire che la shell Bourne era ovunque nel mondo Unix entro il 1983. Questa è una buona approssimazione a "per sempre" nel settore informatico. MS-DOS ottenne un filesystem gerarchico quell'anno (awww, che cuuute!) E il primo Macintosh a 24 bit con il suo schermo da 9 "in bianco e nero - non in scala di grigi, letteralmente in bianco e nero - non sarebbe uscito fino all'inizio del prossimo anno.

  2. La shell Thompson era piuttosto primitiva per gli standard odierni. Era solo una shell di comandi interattiva, piuttosto che l'ambiente di programmazione degli script che ci aspettiamo oggi. Aveva cose come pipe e reindirizzamento I / O, che noi consideriamo come parte prototipica di una "shell Unix", in modo da pensare alla shell dei comandi MS-DOS come ottenerli da Unix.

    La shell Bourne inoltre sostituito il guscio PWB , che ha aggiunto cose importanti al guscio Thompson come programmabilità ( if, switche while) ed una prima forma di variabili di ambiente. La shell PWB è ancora meno ricordata della shell Thompson poiché non faceva parte di ogni versione di Unix.

  3. Quando qualcuno non è specifico sulla compatibilità della shell POSIX vs Bourne, c'è un'intera gamma di cose che potrebbero significare.

    Ad un estremo, potrebbero usare la shell Bourne del 1979 come base. Un " shcopione compatibile" in questo senso significherebbe ci si aspetta per funzionare perfettamente sul vero Bourne shell o uno dei suoi successori e cloni: ash, bash, ksh, zsh, etc.

    Qualcuno all'altro estremo assume invece la shell specificata da POSIX come base. In questi giorni prendiamo così tante funzionalità della shell POSIX come "standard" che spesso dimentichiamo che non erano effettivamente presenti nella shell Bourne: aritmetica integrata, controllo dei lavori, cronologia dei comandi, alias, modifica della riga di comando, la $()forma del comando sostituzione, ecc.

  4. Sebbene la shell Korn abbia radici che risalgono ai primi anni '80, AT&T non lo ha spedito in Unix fino alla System V Release 4 nel 1988. Dato che così tanti Unix commerciali sono basati su SVR4, questo ha aggiunto kshpraticamente ogni Unix commerciale pertinente dal fine degli anni '80 in poi.

    (Alcuni strani aromi Unix basati su SVR3 e precedenti si aggrapparono a pezzi di mercato dopo l'uscita di SVR4, ma furono i primi contro il muro quando venne la rivoluzione .)

    Il 1988 è anche l'anno in cui esce il primo standard POSIX , con la sua "POSIX shell" basata su shell Korn. Più tardi, nel 1993, uscì una versione migliorata della shell Korn. Dal momento che POSIX ha efficacemente inchiodato l'originale, kshbiforcuto in due versioni principali: ksh88e ksh93, dal nome degli anni coinvolti nella loro divisione.

    ksh88non è completamente compatibile con POSIX, anche se le differenze sono piccole, quindi alcune versioni della ksh88shell sono state patchate per essere compatibili con POSIX. (Questo da un'interessante intervista su Slashdot con il Dr. David G. Korn . Sì, il ragazzo che ha scritto la shell.)

    ksh93è un superset completamente compatibile della shell POSIX . Lo sviluppo su ksh93è stato sporadico da quando il repository di fonti primarie si è spostato da AT&T a GitHub con l'ultima versione di circa 3 anni mentre scrivo, ksh93v. (Il nome di base del progetto rimane ksh93con i suffissi aggiunti per indicare le versioni di rilascio oltre il 1993.)

    I sistemi che includono una shell Korn come cosa separata dalla shell POSIX di solito la rendono disponibile come /bin/ksh, sebbene a volte si nasconda altrove.

    Quando parliamo kshdella shell Korn per nome, stiamo parlando di ksh93funzionalità che la distinguono dai suoi sottoinsiemi di shell Bourne e POSIX compatibili con le versioni precedenti. Raramente ti imbatti in puro ksh88oggi.

  5. AT&T ha mantenuto il codice sorgente della shell Korn proprietario fino a marzo 2000 . A quel punto, l'associazione di Linux con GNU Bash era molto forte. Bash e ksh93 ciascuno presentano vantaggi rispetto all'altro , ma a questo punto l'inerzia mantiene Linux strettamente associato a Bash.

    Per quanto riguarda il motivo per cui i primi venditori di Linux più comunemente scelgono GNU Bash pdksh, che era disponibile al momento in cui Linux stava per iniziare, immagino che sia perché gran parte del resto della userland proveniva anche dal progetto GNU . Bash è anche un po 'più avanzato di pdksh, poiché gli sviluppatori di Bash non si limitano a copiare le funzionalità della shell Korn.

    Il lavoro si è pdkshinterrotto circa quando AT&T ha rilasciato il codice sorgente sulla vera shell Korn. Ci sono due forcelle principali che ancora mantenute, tuttavia: l'OpenBSD pdkshe MirBSD Korn Shell,mksh .

    Trovo interessante che mkshsia l'unica implementazione della shell Korn attualmente impacchettata per Cygwin.

  6. GNU Bash va oltre POSIX in molti modi, ma puoi chiedergli di funzionare in una modalità POSIX più pura .

  7. csh/ tcshera di solito la shell interattiva predefinita su Unix BSD all'inizio degli anni '90.

    Essendo una variante BSD , le prime versioni di Mac OS X erano così, attraverso Mac OS X 10.2 "Jaguar" . OS X ha cambiato la shell predefinita da tcshBash in OS X 10.3 "Panther" . Questa modifica non ha influito sui sistemi aggiornati da 10.2 o precedenti. Gli utenti esistenti su quei sistemi convertiti hanno mantenuto la tcshshell.

    FreeBSD afferma di usare ancora tcshcome shell predefinita , ma sulla VM di FreeBSD 10 che ho qui, la shell predefinita sembra essere una delle varianti di shell Almquist compatibili con POSIX . Questo vale anche su NetBSD.

    pdkshInvece OpenBSD usa un fork di come shell predefinita.

    La maggiore popolarità di Linux e OS X fa sì che alcune persone desiderino che anche FreeBSD passi a Bash, ma non lo faranno presto per ragioni filosofiche . È facile cambiarlo , se questo ti dà fastidio.

  8. Al giorno d'oggi è raro trovare un sistema con una shell Bourne veramente vanigliata /bin/sh. Devi fare di tutto per trovare qualcosa di sufficientemente vicino per test di compatibilità.

    Sono a conoscenza di un solo modo per eseguire una vera shell Bourne vintage del 1979 su un computer moderno: utilizzare le immagini del disco Ancient Unix V7 con il simulatore SIMH PDP-11 del Computer History Simulation Project . SIMH funziona praticamente su tutti i computer moderni , non solo su Unix. SIMH funziona anche su Android e iOS .

    Con OpenSolaris , Sun ha acquistato per la prima volta la versione SVR4 della shell Bourne. Prima di ciò, il codice sorgente per le versioni post-V7 della shell Bourne era disponibile solo per quelli con una licenza di codice sorgente Unix.

    Tale codice è ora disponibile separatamente dal resto del defunto progetto OpenSolaris da un paio di fonti diverse.

    La fonte più diretta è il progetto della shell Heirloom Bourne . Questo è diventato disponibile poco dopo l'uscita originale di OpenSolaris del 2005. Nei mesi successivi sono stati eseguiti alcuni lavori di portabilità e correzione dei bug, ma poi lo sviluppo del progetto si è interrotto.

    Jörg Schilling ha svolto un lavoro migliore nel mantenere una versione di questo codice come oshnel suo pacchetto Schily Tools . Vedi sopra per ulteriori informazioni al riguardo.

    Tenere presente che queste shell derivate dalla versione del codice sorgente del 2005 contengono supporto per set di caratteri multi-byte , controllo dei processi , funzioni della shell e altre funzionalità non presenti nella shell Bourne originale del 1979.

    Un modo per capire se ci si trova su una shell Bourne originale è vedere se supporta una funzionalità non documentata aggiunta per facilitare la transizione dalla shell Thompson: ^come alias per |. Vale a dire, un comando simile ls ^ moredarà un errore su una shell di tipo Korn o POSIX, ma si comporterà come ls | moresu una vera shell Bourne.

  9. Occasionalmente incontri un fish, scsho rc/esaderente, ma sono anche più rari dei fan della shell C.

    La rcfamiglia di shell non è comunemente usata sui sistemi Unix / Linux, ma la famiglia è storicamente importante, ed è così che ha guadagnato un posto nel diagramma sopra. rcè la shell standard del Plan 9 del sistema operativo Bell Labs , una sorta di successore della decima edizione di Unix , creata nell'ambito della continua ricerca di Bell Labs nella progettazione del sistema operativo. È incompatibile con la shell Bourne e C a livello di programmazione; probabilmente c'è una lezione lì dentro.

    La variante più attiva di rcsembra essere quella mantenuta da Toby Goodwin , che si basa sul rcclone Unix di Byron Rakitzis.


Se ti piace conoscere più relazioni, ad es. Con UNOS "comando", "bsh" e la recente Bourne Shell, mandami un messaggio. Come suggerimento: il comando UNOS aveva un comando incorporato "do" che fungeva da script di shell a una riga con argomenti. Questa idea è stata trasferita nella Bourne Shell come "dosh" e consente alias parametrizzabili, qualcosa che non si può ottenere da ksh o bash.
schily,

Vale la pena notare che lo stesso pdksh si basa sulla shell Forsyth. Per lo più dimenticato oggi, ma ha un certo significato storico nell'eredità pdksh ma anche perché era la shell di alcune versioni di minix ed era stato portato su msdos.
Stéphane Chazelas,

25

"sh compatibile" si riferisce a POSIXsh , la shell di base che deve esistere su tutti i sistemi compatibili. Uno script sh-compatibile dovrebbe funzionare su qualsiasi macchina compatibile con POSIX.

La ragione per cui è necessario dirlo è che comunemente /bin/shè un link simbolico a /bin/bash, che ha lasciato alcuni bashismi scivolare in script che si dichiarano di utilizzare shcon #!/bin/sh. Questi script non funzionano su sistemi che non usano bashcome /bin/sh, inclusi alcuni Unices commerciali per sempre, e Debian e derivati recentemente.

In particolare c'è stata una tendenza da usare dash, Debian Almquish Shell, come impostazione predefinita shultimamente, perché è più piccola e pensata per essere più veloce. Quella tendenza ha messo in luce molti di quei Bashismi che erano in presunti shscript. Descrivere qualcosa come "sh compatibile" indica che è esplicitamente progettato per funzionare con questi sistemi rimanendo interamente all'interno del linguaggio specificato da POSIX : tutte le shell implementeranno un superset di tale funzionalità, quindi è garantito che funzioni ovunque, ma le loro estensioni non lo sono compatibile tra loro.

Diverse shell hanno le loro storie di sviluppo e sono divergenti nel tempo in diverse direzioni, poiché hanno aggiunto funzioni per aiutare l'uso interattivo per i loro utenti o estensioni di script come array associativi. Uno script "sh-incompatibile" userebbe alcune di queste funzionalità di estensione non standard, come i [[condizionali di Bash .

La non-POSIX dispone in bashe tcshed zshe tutte le altre shell attuali sono utili , e ci sono un sacco di occasioni in cui si potrebbe desiderare o bisogno. Semplicemente non dovrebbero essere usati in uno script con cui si dichiara di funzionare /bin/sh, perché non puoi fare affidamento su quelle funzionalità presenti shnell'implementazione di base sul sistema su cui stai eseguendo.

Uno script che deve usare, per esempio, array associativi, dovrebbe garantire che venga eseguito bashanziché sh:

#!/bin/bash
declare -A array

Funzionerà ovunque con bash. Gli script che non necessitano della funzionalità estesa e sono pensati per essere portatili dovrebbero dichiarare che usano she si attengono al linguaggio di comando della shell di base.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.