Quando sh è un collegamento simbolico a bash o dash, bash si limita alla conformità POSIX, quindi dovrebbe essere compatibile al 100% con sh?


8

Dalla differenza tra bash e sh :

Rispondi alla domanda: se hai /bin/shcome link bash, allora bash non si comporterà allo stesso modo quando viene chiamato così /bin/shcome quando viene chiamato come /bin/bash. Se chiamato come sh, si limiterà principalmente alla conformità POSIX oltre a un set limitato di estensioni.

Vuol dire che ogni volta che mi imbatto in uno script di shell in Linux con una shebang a sh:, #!/bin/shanche se su quella distro, bin/shè un link simbolico a un'altra shell, come dash o bash, dovrebbe essere compatibile al 100% con la shell bourne, dal momento che si limita a una serie limitata di estensioni? Quindi potrei eseguirli in FreeBSD? C'è un'eccezione a questo? O dovrei essere sicuro di supporre che funzionerà?

Quindi, se su una distro, bin/shc'è un collegamento simbolico a bin/bash, e uno script usa #!/bin/she lo script contiene bashism, non funzionerà, dal momento che bash sarà come essere in modalità sh?

Risposte:


16

No, se /bin/shè un collegamento simbolico a bash bash entra solo in modalità posix - da man bash :

Quando viene invocato come sh, bash entra in modalità posix dopo la lettura dei file di avvio.

Se ora cerchi la modalità posix nella manpage di bash vedrai che alcuni builtin della shell gradiscono timeo si sourcecomportano diversamente. Questo è tutto. bashishms come scrivere functionprima di dichiarare una funzione o usare sourceinvece di .ancora funzioneranno, ma i comandi potrebbero comportarsi diversamente.

Quindi, se /bin/shè un /bin/bashcollegamento simbolico a tutti i tipici bashishm funzionano ancora.

Per un elenco piuttosto ampio di differenze nella modalità Posix, dai un'occhiata al manuale di riferimento di bash .


Quindi immagino che la cosa migliore da fare sia testare tutti gli script nello strumento checkbashism. Ho sentito che alcune distro, come Debian e Ubuntu (necessitano di conferma per questo) avevano il loro bin / sh ora link simbolico al trattino. Dash è compatibile con la shell bourn? Se sì, almeno tutti gli script della shell Debian e Ubuntu dovrebbero andare bene sotto FreeBSD.
user1115057

@utente1115057 solo script di shell con /bin/shcome shebang. Uno script di shell può ancora essere esplicitamente utilizzato /bin/bash. Comunque la maggior parte degli script di shell probabilmente funzionerà bene sotto / bin / sh ma il problema sarà rappresentato dagli strumenti utente, ad es. La maggior parte degli script di shell si aspetta che l'utente utilizzi GNU che probabilmente sarà più un problema che un semplice errore di sintassi. Ho anche aggiunto un link al riferimento bash che elenca i diversi comportamenti in modalità posix
Ulrich Dangel

Ok da quello che ho letto, BSD usa ash come bin / sh, mentre Debian e Ubuntu usano dash. Se quelle shell sono compatibili, significa che non avrò più problemi con shebang #! / Bin / sh. Ma come hai detto, ci saranno altri problemi relativi alla userland ...
user1115057

Anche il trattino @ user1115057 non è perfetto, ad esempio wiki.ubuntu.com/DashAsBinSh/#echo comunque la maggior parte degli script di shell sono piuttosto semplici e possono essere portati abbastanza facilmente ... buona fortuna
Ulrich Dangel

Ma trattino e cenere sono compatibili, giusto?
user1115057

8

Sembra esserci un po 'di confusione attorno alla conchiglia di Bourne. La shell Bourne era una shell Unix decenni fa, nei giorni pre-POSIX. Oggi "sh" è un'implementazione o un'altra di una shell che implementa la specifica POSIX, tra cui abbiamo bash, pdksh, AT&T ksh, nuove shell Almquist e i loro derivati ​​che sono stati resi POSIX compatibili (inclusa la "sh" di alcuni BSD , altri BSD sono basati su pdksh e Debian ash (trattino)). Anche zsh ha una modalità in cui è per lo più conforme a POSIX.

La shell Bourne non è conforme a POSIX e al giorno d'oggi non può essere trovata su molti sistemi. Dove si trova la shell Bourne o dove non lo è, ci sarà sempre una "sh" che è conforme POSIX (e non sarà la shell Bourne), generalmente /binmentre una notevole (fastidiosa) eccezione è Solaris.

Si noti che prima della shell Bourne, e stiamo parlando più di 30 anni fa, "sh" era la shell Thompson. Non stiamo più scrivendo script compatibili con la shell Thompson. Allo stesso modo, dovremmo smettere di pensare a "sh" come alla shell Bourne.

Ora "sh" è una specifica, non molte varianti a volte incompatibili di un'implementazione. Ciò rende molto più semplice scrivere script portatili. Segui le specifiche .

Questo vale per "sh" e tutte le utility standard (sed, cut, tr ...)


+1 per "scrivere nelle specifiche". Ma purtroppo spesso non è sufficiente per la portabilità. Ad esempio, cosa succede se si desidera utilizzare modelli in stile egrep in sed? Le specifiche non lo prevedono. Sui sistemi con utility basate su Gnu (o BusyBox), si utilizza sed -r. Sui sistemi con utilità basate su BSD, si utilizza sed -E. Sed di FreeBSD accetta entrambi, ma Mac OS X accetta solo -E. E così via e così via.
dubiousjim,

Questo è il punto. La specifica non lo fornisce, quindi non è possibile utilizzarlo in modo portabile / POSIX. Se usi BRE, questo funzionerà su tutti i sistemi POSIX conformi, questa è una garanzia data da POSIX, ecco perché è utile. Al di fuori di POSIX, come dici tu, non c'è speranza in quanto seds o non supporta ERE o lo supporta con un'opzione diversa o diversa sintassi ERE. Nota che gli ERE sono meno capaci dei BRE (solo la sintassi è estesa negli ERE per farti risparmiare un po 'di battitura. Gli ERE possono essere tradotti in BRE, il contrario non è vero (BRE \(...\)\1non ha traduzione negli ERE standard).
Stéphane Chazelas

1
Mi rendo conto che gli ERE (POSIX) mancano di riferimenti indietro; in effetti ho partecipato alla modifica di quella parte dello standard. Non è corretto che gli ERE POSIX siano strettamente meno capaci dei BRE, poiché nello standard attuale l'alternanza non è definita per i BRE. Tuttavia, non sono a conoscenza di alcun motore regex che non rispetti i \|BRE. Sono tutto per scrivere nel modo più portabile possibile. Stavo solo facendo l'osservazione (ho pensato ampiamente apprezzato) che questo può essere doloroso, e talvolta scrivere su POSIX non è semplicemente possibile. Da qualche parte ci sono collegamenti che mostrano molte di queste perversioni; li cercherò.
dubiousjim,

buon punto sull'alternanza, me ne sono dimenticato e rimango corretto. Con sed, è improbabile che si blocchi, poiché è possibile utilizzare diverse espressioni per abbinare le regexps alternative. C'è awk nel toolchest standard che può essere utilizzato se sono necessari ERE. Mi trovo molto raramente dal toolchest standard e, quando lo faccio, sono in genere casi in cui un'altra lingua come il perl è più appropriata, ma vedo il tuo punto (anche se penso ancora che sia accanto al punto in questo thread sulla scrittura di script portatili)
Stéphane Chazelas,

Un esempio che ho pensato di sbrigativo: le linee shebang (nella parte superiore di ogni script di shell) non sono specificate in POSIX. Inoltre, non sono sicuro di aver mai usato un sistema conforme al 100% con POSIX. Ad esempio, POSIX afferma che puoi includere nuove righe all'interno, ${VAR:=stuff...here}ma molte shell non ti consentono, devi mettere tra virgolette stuff...here.
dubiousjim,
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.