GNU/Linux >> Linux Esercitazione >  >> Linux

Cosa significa essere "sh compatibile"?

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

Cosa significa per una shell o un altro programma essere "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 comunque una risposta diretta su cosa significa essere "compatibili con sh". Una ragionevole aspettativa potrebbe essere che "sh compatibile" significhi "implementa il linguaggio di comando della shell", ma allora perché ci sono così tante shell "sh compatibili" e perché sono diverse?

Risposta accettata:

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

La shell Bourne è stata rilasciata pubblicamente per la prima volta nel 1979 come parte di Unix V7. Poiché praticamente tutti i sistemi Unix e simili a Unix discendono da Unix V7, anche se solo spiritualmente, la shell Bourne è stata con noi "per sempre".¹

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

Sia la shell Bourne che quella Thompson erano chiamate sh . La shell specificata da POSIX è anche chiamata sh . Quindi, quando qualcuno dice sh -compatibili, si riferiscono a questa serie di conchiglie. Se volessero essere precisi, direbbero "shell POSIX" o "shell Bourne".³

La shell POSIX è basata sulla versione del 1988 di KornShell, che a sua volta doveva sostituire la shell Bourne su AT&T Unix, scavalcando la shell BSD C in termini di funzionalità.⁴ Nella misura in cui ksh è l'antenato della shell POSIX, la maggior parte dei sistemi Unix e simili a Unix include oggi alcune varianti della shell Korn. Le eccezioni sono generalmente piccoli sistemi embedded, che non possono permettersi lo spazio occupato da una shell POSIX completa.

Detto questo, la shell Korn - in quanto cosa distinta dalla shell POSIX - non è mai diventata davvero popolare al di fuori del mondo commerciale Unix. Questo perché la sua ascesa corrispondeva ai primi anni della commercializzazione di Unix, quindi fu coinvolto nelle guerre Unix. BSD Unixes lo ha evitato a favore della shell C e il suo codice sorgente non era disponibile gratuitamente per l'uso in Linux quando è stato avviato.⁵ Quindi, quando i primi distributori di Linux cercarono una shell di comando da abbinare al loro kernel Linux, di solito sceglievano GNU Bash, uno di quelli sh -compatibili di cui stai parlando.⁶

Quella prima associazione tra Linux e Bash ha praticamente segnato il destino di molte altre shell, inclusa ksh , csh e tcsh . Ci sono ancora oggi irriducibili che usano quei proiettili, ma sono molto in minoranza.⁷

Tutta questa storia spiega perché ai creatori di relativi ritardatari piace bash , zsh e yash ha scelto di renderli sh -compatibile:la compatibilità Bourne/POSIX è il minimo che una shell per sistemi simili a Unix deve fornire per ottenere un'adozione diffusa.

In molti sistemi, la shell dei comandi interattiva predefinita e /bin/sh sono cose diverse. /bin/sh può 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 dell'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 conteneva codice sorgente AT&T, 4.4BSD-Lite. La shell di Almquist è spesso chiamata ash , anche se installato come /bin/sh .

    4.4BSD-Lite a sua volta divenne la base per tutti i moderni derivati ​​BSD, con /bin/sh rimanendo come un derivato Almquist nella maggior parte di essi, con una grande eccezione annotata di seguito. Puoi vedere questa discendenza diretta nei repository del codice sorgente per NetBSD e FreeBSD:stavano inviando un derivato della shell Almquist dal giorno 1.

    Ci sono due importanti ash fork al di fuori del mondo BSD:

    1. dash , notoriamente adottato da Debian e Ubuntu nel 2006 come /bin/sh predefinito implementazione. (Bash rimane l'impostazione predefinita interattiva shell dei comandi in derivati ​​Debian.)

    2. Il ash comando in BusyBox, che è spesso usato nei Linux embedded e può essere usato per implementare /bin/sh . Dal momento che postdate dash ed era derivato dal vecchio ash di Debian pacchetto, ho scelto di considerarlo un derivato di dash anziché ash , nonostante il nome del comando all'interno di BusyBox.

      (BusyBox include anche un'alternativa meno funzionale a ash chiamato hush . In genere solo uno dei due verrà integrato in un dato binario di BusyBox:ash per impostazione predefinita, ma hush quando lo spazio è davvero stretto. Pertanto, /bin/sh sui sistemi basati su BusyBox non è sempre dash -come.)

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

    Questa scelta è tipica delle 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 ksh93 Estensioni POSIX , come in OpenBSD. Sebbene la shell OpenBSD modifichi il comportamento per evitare sintassi e incompatibilità semantiche con le shell Bourne e POSIX quando viene chiamata come sh , non disabilita nessuna delle sue estensioni pure, essendo quelle che non sono in conflitto con le shell precedenti.

    Questo non è comune; non dovresti aspettarti ksh93 funzioni in /bin/sh .

Ho usato "script di shell" sopra come 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, devi fornire un qualificatore, come "Script di shell C". Anche su sistemi in cui una shell della famiglia C è la shell interattiva predefinita, è meglio usare la shell Bourne per lo scripting.

È significativo che quando Wikipedia classifica le shell Unix, le raggruppa in compatibili con la shell Bourne, compatibili con la shell C e "altro".

Correlati:comando intuitivo per elencare tutti gli utenti sul sistema Ubuntu?

Questo diagramma può aiutare:

(Fai clic per la versione SVG, 31 kB, o visualizza la versione PNG a grandezza naturale, 218 kB.)

Cosa significherebbe essere "sh incompatibile"?

Qualcuno che parla di un sh -cosa 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 shell Bourne e C.

  3. Stanno parlando di alcune caratteristiche specifiche in una shell della famiglia Bourne che non è in tutte le altre shell della famiglia Bourne. ksh93 , bash e zsh in particolare hanno molte caratteristiche che non esistono nelle vecchie shell "standard". Questi tre sono anche reciprocamente incompatibili in molti modi, una volta che si va oltre il POSIX condiviso/ksh88 base.

È un classico errore scrivere uno script di shell con un #!/bin/sh linea shebang nella parte superiore ma per utilizzare le estensioni della shell Bash o Korn all'interno. Da /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 sui sistemi in cui /bin/sh è qualcosa della più ampia famiglia di conchiglie Bourne. La migliore pratica consiste nell'usare #!/bin/bash o #!/bin/ksh righe shebang se lo script utilizza tali estensioni.

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

  • Esegui checkbashisms su 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, più alcune altre funzionalità minori.

  • Eseguilo sotto obosh dal progetto Schily Tools, una versione migliorata della shell Bourne resa open source da Sun come parte di OpenSolaris nel 2005, rendendolo uno dei modi più semplici per ottenere una shell Bourne in stile 1979 su un computer moderno.

    La distribuzione di Schily Tools include anche bosh , una shell di tipo POSIX con molte funzioni 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. Tende ad essere più conservativo nel suo set di funzionalità rispetto a bash , zsh e le versioni avanzate di ksh93 .

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

  • Esamina il capitolo Portable Shell Programming nel manuale di 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 può essere migliorata solo interrompendo la compatibilità con le versioni precedenti.

  • Qualcuno ha pensato a un modo diverso per far funzionare qualcosa, che gli piace di più, ma che non è lo stesso modo in cui funzionava il vecchio.

  • Qualcuno ha provato a reintrodurre un vecchio standard senza capirlo completamente, quindi ha incasinato e creato una differenza involontaria.

Note a piè di pagina e digressioni :

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

    Tuttavia, le prime versioni standalone di BSD (2.9BSD e 3BSD) erano basate su V7 o sul suo successore portatile UNIX/32V, quindi facevano 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 nuovi tipi di computer come le workstation Vaxen e Unix. 2.9BSD era essenzialmente la versione PDP di 4.1cBSD; erano codice contemporaneo e condiviso. I PDP non sono semplicemente scomparsi quando è arrivato il VAX, quindi la linea 2BSD è ancora in movimento.)

    È sicuro dire che la shell Bourne era ovunque nel mondo Unix nel 1983. Questa è una buona approssimazione di "per sempre" nell'industria informatica. MS-DOS ha ottenuto un filesystem gerarchico quell'anno (awww, che bello!) e il primo Macintosh a 24 bit con il suo schermo da 9″ in bianco e nero — non in scala di grigi, letteralmente nero e bianco — 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 di script che ci aspettiamo oggi. Aveva cose come pipe e reindirizzamento I/O, che pensiamo come prototipicamente parte di una "shell Unix", quindi pensiamo alla shell dei comandi di MS-DOS come se li ottenesse da Unix.

    La shell Bourne ha anche sostituito la shell PWB, che ha aggiunto cose importanti alla shell Thompson come la programmabilità (if , switch e while ) e una prima forma di variabili d'ambiente. La shell PWB è ancora meno ricordata della shell Thompson poiché non faceva parte di tutte le versioni di Unix.

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

    Ad un estremo, potrebbero utilizzare il guscio Bourne del 1979 come linea di base. Un "sh -script compatibile" in questo senso significherebbe che dovrebbe funzionare perfettamente sulla vera shell Bourne o su uno qualsiasi dei suoi successori e cloni:ash , bash , ksh , zsh , ecc.

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

  4. Sebbene la shell Korn abbia radici che risalgono ai primi anni '80, AT&T non l'ha spedita in Unix fino alla versione 4 di System V nel 1988. Poiché così tanti Unix commerciali sono basati su SVR4, questo ha messo ksh praticamente in tutti gli Unix commerciali rilevanti dalla fine degli anni '80 in poi.

    (Alcuni strani gusti Unix basati su SVR3 e in precedenza hanno tenuto pezzi di mercato dopo il rilascio di SVR4, ma sono stati i primi contro il muro quando è arrivata la rivoluzione.)

    Il 1988 è anche l'anno in cui è uscito il primo standard POSIX, con la sua "shell POSIX" basata sulla shell Korn. Più tardi, nel 1993, uscì una versione migliorata della shell Korn. Poiché POSIX ha effettivamente inchiodato l'originale in posizione, ksh biforcato in due versioni principali:ksh88 e ksh93 , dal nome degli anni coinvolti nella loro scissione.

    ksh88 non è del tutto compatibile con POSIX, anche se le differenze sono piccole, così che alcune versioni di ksh88 shell sono state patchate per essere compatibili con POSIX. (Questo da un'interessante intervista su Slashdot con il dottor David G. Korn. Sì, il ragazzo che ha scritto la shell.)

    ksh93 è un superset completamente compatibile della shell POSIX. Sviluppo su ksh93 è stato sporadico da quando il repository di origine primaria è stato spostato da AT&T a GitHub con la versione più recente di circa 3 anni mentre scrivo questo, ksh93v. (Il nome di base del progetto rimane ksh93 con suffissi aggiunti per indicare le versioni successive al 1993.)

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

    Quando parliamo di ksh o la shell Korn per nome, stiamo parlando di ksh93 caratteristiche che lo distinguono dai suoi sottoinsiemi di shell Bourne e POSIX compatibili con le versioni precedenti. Raramente ti imbatti nel puro ksh88 oggi.

  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 ognuno ha dei vantaggi rispetto all'altro, ma a questo punto l'inerzia mantiene Linux strettamente associato a Bash.

    Sul motivo per cui i primi fornitori di Linux scelgono più comunemente GNU Bash su pdksh , che era disponibile all'inizio di Linux, suppongo sia perché gran parte del resto della userland proveniva anche dal progetto GNU. Bash è anche un po' più avanzato di pdksh , poiché gli sviluppatori Bash non si limitano a copiare le funzionalità della shell Korn.

    Lavora su pdksh si è fermato all'incirca nel momento in cui AT&T ha rilasciato il codice sorgente alla vera shell Korn. Tuttavia, ci sono due fork principali che sono ancora mantenuti:OpenBSD pdksh e la shell Korn MirBSD, mksh .

    Trovo interessante che mksh è l'unica implementazione della shell Korn attualmente confezionata per Cygwin.

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

  7. csh /tcsh era solitamente la shell interattiva predefinita su BSD Unix fino all'inizio degli anni '90.

    Essendo una variante BSD, le prime versioni di Mac OS X erano in questo modo, tramite Mac OS X 10.2 "Jaguar". OS X ha cambiato la shell predefinita da tcsh a Bash in OS X 10.3 "Pantera". Questa modifica non ha influito sui sistemi aggiornati da 10.2 o precedenti. Gli utenti esistenti su quei sistemi convertiti hanno mantenuto il loro tcsh guscio.

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

    OpenBSD usa un fork di pdksh invece 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. È raro trovare un sistema con una shell Bourne veramente vanigliata come /bin/sh in questi giorni. Devi fare di tutto per trovare qualcosa di sufficientemente vicino ad esso per i 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 quelli simili a Unix. SIMH funziona anche su Android e iOS.

    Con OpenSolaris, Sun ha reso open source per la prima volta la versione SVR4 della shell Bourne. In precedenza, il codice sorgente per le versioni successive alla V7 della shell Bourne era disponibile solo per coloro che disponevano di una licenza del codice sorgente Unix.

    Quel 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 la versione originale del 2005 di OpenSolaris. Alcuni lavori di portabilità e correzione dei bug sono stati eseguiti nei mesi successivi, ma poi lo sviluppo del progetto è stato interrotto.

    Jörg Schilling ha fatto un lavoro migliore nel mantenere una versione di questo codice come obosh nel suo pacchetto Schily Tools. Vedi sopra per ulteriori informazioni su questo.

    Tieni presente che queste shell derivate dalla versione del codice sorgente del 2005 contengono supporto per set di caratteri multibyte, controllo del lavoro, funzioni della shell e altre funzionalità non presenti nella shell Bourne originale del 1979.

    Un modo per sapere 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 come ls ^ more darà un errore su una shell di tipo Korn o POSIX, ma si comporterà come ls | more su una vera shell Bourne.

  9. Occasionalmente incontri un fish , scsh o rc/es aderenti, ma sono persino più rari dei fan della shell C.

    Il rc famiglia di shell non è comunemente usata su sistemi Unix/Linux, ma la famiglia è storicamente importante, ed è così che si è guadagnata un posto nel diagramma sopra. rc è la shell standard del sistema operativo Plan 9 del sistema operativo Bell Labs, una sorta di successore della decima edizione di Unix, creata come parte della continua ricerca di Bell Labs sulla progettazione del sistema operativo. È incompatibile sia con Bourne che con la shell C a livello di programmazione; probabilmente c'è una lezione lì dentro.

    La variante più attiva di rc sembra essere quello gestito da Toby Goodwin, che si basa su Unix rc clone di Byron Rakitzis.

Correlati:estrarre il file dall'immagine della finestra mobile?
Linux
  1. Cosa significa "-" (doppio trattino)?

  2. Cosa significa e commerciale alla fine di una riga di script di shell?

  3. Cosa significa "rm is hash"?

  4. Che cosa significa [e-mail protetta] in uno script di shell?

  5. Cosa succede se [[ $? -ne 0 ]]; significa in .ksh

Cosa significa chmod 777

Nessuna variabile DISPLAY X11 - cosa significa?

Cosa significa uccidere -3?

Cosa fa % nelle stringhe della shell di Linux?

Cosa significa la capacità ep?

Cosa significa %st in alto?