L'hai fatto al contrario. /bin/shnon è quasi mai una shell Bourne in questi giorni, ed è quando è¹ che hai un problema quando usi un #! /bin/shbang bang.
La shell Bourne era una shell scritta alla fine degli anni '70 e sostituì la precedente shell Thompson (chiamata anche sh). All'inizio degli anni '80, David Korn scrisse alcune estensioni per la shell Bourne, sistemò alcuni bug e progettò goffaggine (e ne introdusse alcune) e la chiamò shell Korn.
All'inizio degli anni '90, POSIX ha specificato il sh linguaggio basato su un sottoinsieme della shell Korn e la maggior parte dei sistemi¹ ha ora cambiato la propria /bin/shcon la shell Korn o una shell conforme a tale specifica. Nel caso dei BSD, hanno gradualmente cambiato la loro /bin/sh, inizialmente (dopo che non potevano più usare la shell Bourne per motivi di licenza) la shell Almquist, un clone della shell Bourne con alcune estensioni ksh, quindi è diventata conforme a POSIX.
Oggi, tutti i sistemi POSIX hanno una shell chiamata sh(il più delle volte, ma non necessariamente in /bin, POSIX non specifica il percorso delle utility che specifica) che è per lo più conforme a POSIX. Si basa generalmente su ksh88, ksh93, pdksh, bash, ash o zsh², ma non sulla shell Bourne poiché la shell Bourne non è mai stata conforme a POSIX³. Alcuni di tali gusci ( bash, zsh, yashe alcuni pdkshderivati consentono una modalità POSIX-compliant Quando invocato come she sono meno compatibili altrimenti).
bash(la risposta GNU alla shell Korn) è in realtà l'unica shell open source (e si potrebbe dire solo attualmente mantenuta poiché le altre sono generalmente basate su ksh88 che non ha ottenuto alcuna nuova funzionalità dagli anni '90) che è stato certificato come essendo conforme a POSIX sh(come parte della certificazione macOS).
Quando scrivi uno script con un #! /bin/sh -she-bang, dovresti usare una shsintassi standard (e dovresti anche usare la sintassi standard per le utility usate in quello script se vuoi essere portatile, non è solo la shell che è coinvolta nell'interpretazione di una shell script), quindi non importa quale implementazione di quell'interprete di shsintassi standard viene utilizzata ( ksh, bash...).
Non importa che quelle shell abbiano estensioni oltre lo standard fintanto che non le usi. È come scrivere codice C, purché si scriva codice C standard e non si utilizzino le estensioni di un compilatore (come gcc) o dell'altro, il codice deve compilare OK indipendentemente dall'implementazione del compilatore, a condizione che il compilatore sia conforme.
Qui, con la vostra #! /bin/shlei-bang, il problema principale sarebbe i sistemi in cui /bin/shè la shell Bourne che, per esempio non supporta le funzionalità standard come $((1+1)), $(cmd), ${var#pattern}... Nel qual caso potrebbe essere necessario work-around come:
#! /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 proposito, Ubuntu /bin/shnon è bashdi default. È in dashquesti giorni, una shell che si basa su NetBSD sh, a sua volta basata sulla shell Almquist che è per lo più conforme a POSIX tranne per il fatto che non supporta i caratteri multi-byte. Su Ubuntu e altri sistemi basati su Debian, puoi scegliere tra bashe dashper /bin/shcon dpkg-reconfigure dash) 4 . shgli script forniti con Debian dovrebbero funzionare allo stesso modo in entrambe le shell poiché sono scritti nello standard delle politiche Debian (un superset dello standard POSIX). Probabilmente troverete opera anche su OK nella zsh's shdi emulazione o bosh(probabilmente non ksh93né yashche non hanno un localbuiltin (richiesto dalla politica Debian ma non POSIX)).
Tutti i sistemi nell'ambito di unix.stackexchange.com hanno un POSIX sh da qualche parte. La maggior parte di loro ha un /bin/sh(potresti trovare quelli molto rari che non hanno una /bindirectory ma probabilmente non ti interessa), e questo è generalmente un shinterprete POSIX (e in rari casi una shell Bourne (non standard) invece ).
Ma shè l'unico eseguibile dell'interprete della shell che puoi essere sicuro di trovare su un sistema. Per le altre shell, puoi essere sicuro che avranno macOS, Cygwin e la maggior parte delle distribuzioni GNU / Linux bash. I sistemi operativi derivati da SYSV (Solaris, AIX ...) avranno generalmente ksh88, possibilmente ksh93. OpenBSD, MirOS avrà un derivato pdksh. macOS avrà zsh. Ma da ciò, non ci sarà alcuna garanzia. Nessuna garanzia sul fatto che una basho più di queste shell vengano installate all'interno /bino altrove (di solito si trova /usr/local/binsu BSD quando installato ad esempio). E ovviamente nessuna garanzia della versione della shell che verrà installata.
Si noti che #! /path/to/executablenon è una convenzione , è una caratteristica di tutti i kernel simili a Unix ( introdotti nei primi anni '80 da Dennis Ritchie ) che consente di eseguire file arbitrari specificando il percorso dell'interprete in una prima riga che inizia con #!. Può essere qualsiasi eseguibile.
Quando si esegue un file la cui prima riga inizia #! /some/file some-optional-arg, il kernel finisce /some/filecon some-optional-arg, il percorso dello script e gli argomenti originali come argomenti. Puoi fare quella prima riga #! /bin/echo testper vedere cosa sta succedendo:
$ ./myscript foo
test ./myscript foo
Quando si utilizza /bin/sh -invece di /bin/echo test, il kernel viene eseguito /bin/sh - ./myscript foo, shinterpreta il codice contenuto archiviato myscripte ignora quella prima riga in quanto è un commento (inizia con #).
¹ Probabilmente l'unico sistema oggi in cui qualcuno di noi si imbatterà in una /bin/shshell basata su Bourne è Solaris 10. Solaris è uno dei pochi Unice che ha deciso di mantenere lì una shell Bourne per compatibilità con le versioni precedenti (il shlinguaggio POSIX non è completamente retrocompatibile con la shell Bourne) e (almeno per le distribuzioni desktop e full server) hanno POSIX shaltrove (in /usr/xpg4/bin/sh, basato su ksh88), ma questo è cambiato in Solaris 11 dove /bin/shora è ksh93. Gli altri sono per lo più defunti.
² Lo era /bin/shdi MacOS / Xzsh , ma in seguito cambiò in bash. L' zshobiettivo principale non è quello di essere utilizzato come shimplementazione POSIX . La sua shmodalità è principalmente quella di poter incorporare o chiamare ( source) il shcodice POSIX negli zshscript
³ Di recente, @schily ha esteso la shell OpenSolaris (base sulla shell SVR4, basata sulla shell Bourne) per renderla conforme a POSIX, chiamata boshma non sono ancora a conoscenza del fatto che sia utilizzata su qualsiasi sistema. Insieme a ksh88ciò, la rende una seconda shell conforme a POSIX basata sul codice della shell Bourne
4 Nelle versioni precedenti, è possibile utilizzare anche la mkshsua lkshincarnazione POSIX . Questa è la shell MirOS (precedentemente MirBSD) basata su pdksh, essa stessa basata sulla shell Forsyth (un'altra reimplementazione della shell Bourne))