Esiste un codice sh che non è un codice bash sintatticamente valido?


31

Esiste un shcodice che non è un codice bash sintatticamente valido (non si verifica sulla sintassi)?

Sto pensando di sovrascrivere shcon bashdeterminati comandi.


1
Immagino che per valido intendessi sintatticamente valido, quindi non verterà sulla sintassi
Alexander Mills,

2
Token diverso? ad esempio ((viene in mente.
ccornà

1
Per alcune distro /usr/bin/shè solo un collegamento simbolico a /usr/bin/bash(sto usando CentOS 7.3 ed è). Dovresti controllare per vedere se shè davvero bashper la tua distribuzione.
Centimane,

1
Qualche anno fa, il mio intero progetto si è rotto quando qualcosa è stato "aggiornato" a Bash. Ho dovuto cambiare tutte le mie linee da Shebang #!/bin/sha #!/bin/bash. Quindi tutto ha funzionato di nuovo, quindi devi stare molto attento. Potrebbe essere successo quando hanno iniziato a usare dash anziché bash per sh.
Joe,

1
@Joe, questo è l'opposto di ciò che l'OP chiede - avevi codice bash che era etichettato erroneamente come codice sh ma non lo era. L'OP chiede se possono avere un codice sh (effettivo, non etichettato in modo errato) che si rompe quando gira con bash, non se possono avere un codice bash che si rompe quando gira con sh (il che è ovvio - se le estensioni bash non lo facevano avere alcun effetto sulle funzionalità linguistiche disponibili, non sarebbero estensioni).
Charles Duffy,

Risposte:


49

Ecco del codice che fa qualcosa di diverso in POSIX sh e Bash:

hello &> world

Se questo non è "valido" per te, non lo so.

In Bash, si reindirizza sia lo standard output e standard error dal hellonel file world. In POSIX sh, viene eseguito helloin background e quindi effettua un reindirizzamento vuoto in world, troncandolo (ovvero viene trattato come & >).

Ci sono molti altri casi in cui le estensioni di Bash faranno la loro cosa quando eseguite bash, e avrebbero effetti diversi in un POSIX puro sh. Ad esempio, l' espansione del controvento è un'altra, e anch'essa funziona allo stesso modo in modalità POSIX di Bash e non.


Per quanto riguarda gli errori di sintassi statici, Bash ha entrambe le parole riservate (come [[e time) non specificate da POSIX, tale che [[ xè un codice shell POSIX valido ma un errore di sintassi Bash e una cronologia di vari bug di incompatibilità POSIX che possono causare errori di sintassi, come quello di questa domanda :

x=$(cat <<'EOF'
`
EOF
)
bash: line 2: unexpected EOF while looking for matching ``'
bash: line 5: syntax error: unexpected end of file

Sintassi-solo errori è una definizione piuttosto pericolosa di "non valido" per qualsiasi circostanza in cui è importante, ma è così.


3
Si noti che mentre l'espansione del controvento rende attualmente non conforme bash (e zsh, pdksh, ksh93), POSIX sta lavorando per aggiungere disposizioni nelle specifiche per consentire l'espansione del controvento (e {fd}>fileun problema simile), in modo che bash possa essere nuovamente conforme (espansione del controvento rimarrebbe non specificato, ma gli script conformi dovrebbero fare echo "{a,b}"se vogliono {a,b}essere stampati). Vedi la discussione che l'ha iniziata
Stéphane Chazelas,


2
Qualcuno che scrive uno script in POSIX scriverà mai un comando come questo? L'OP sta andando da sh a bash, e dalla mia comprensione questo sembra che sarebbe più un problema andare nella direzione opposta?
Ricco

1
@Rich: certo. Non uso alcun sistema in cui /bin/shè bash, quindi se non fossi attivamente consapevole di questo bashismo, scrivere una riga di comando potrebbe facilmente accadere. La spaziatura nella risposta la fa sembrare improbabile, ma hello&>worldè meno inverosimile.
R ..

2
In realtà ho visto un bug a causa della &>differenza proprio il mese scorso!
Gordon Davisson,

16

Un breve esempio:

time()(:)

timein Bash è una parola riservata e si comporta diversamente dal timeprogramma. È molto probabile che infrangerai alcuni script pratici cercando di analizzare il risultato timeusando bash. Ma tecnicamente non è un errore di sintassi. La ridefinizione timecome funzione sarebbe rara ma causa un errore di sintassi come specifica questa domanda.

Un esempio più breve:

a():

Valido in dash, ma non conforme a POSIX.


3
Più in generale, qualsiasi parola che sia una parola chiave non standard o un comando incorporato in Bash causerà lo stesso effetto. In aggiunta a time, c'è roba come declare, function, select, e coproc. Sebbene alcuni di questi siano esplicitamente contrassegnati come non specificati nello standard ( parole chiave e builtin / utility ), ma non riesco a vedere ad esempio timeo coprocnell'elenco. E l'utilizzo --posixnon sembra aiutare.
ilkkachu,
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.