Come usare Bash per sh in Ubuntu


13

Sto installando un enorme programma, che ha le sue risorse come rpmfile. Si è bloccato sulla linea di

#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]

Apparentemente, shlavora bashcon Red Hat Linux con questa sintassi, ma dà l'errore di unexpected operatorUbuntu.

Non posso cambiare lo script in bashcome lo script proviene dal rpmpacchetto. Posso estrarre e reimballare il rpmpacchetto, ma potrebbero esserci molti di questi script.

Esiste un modo per modificare l'impostazione predefinita della shell da trattare #!/bin/shcome basho qualsiasi altra cosa in grado di gestire l' [operatore?


5
L'unica cosa che non va è quella ==che dovrebbe essere =. Quello e che le espansioni variabili dovrebbero essere racchiuse tra virgolette.
Kusalananda

4
[non è un operatore, ma un comando incorporato che viene chiamato test. L'operatore imprevisto è ==e questo dovrebbe essere sostituito =perché non è conforme a POSIX.
schily

La seconda unica cosa che non va è che $SCITEGICPERLHOMEdovrebbe essere citata.
l0b0

12
Dovresti lamentarti con l'autore del programma. Se lo usano #!/bin/sh, dovrebbero assicurarsi di utilizzare solo le funzionalità della shell POSIX, non le bashestensioni. Questo programmatore è molto sciatto. Dovrebbe correggere il suo codice o usarlo #!/bin/bash.
Barmar

Per le persone che si chiedono altri problemi simili ecco un elenco di " Bashismi ". Vedi anche questa domanda .
Captain Man

Risposte:


21

Esistono più programmi che implementano la lingua di /bin/sh. Su Ubuntu, /bin/shè dash, progettato per essere veloce, per utilizzare una piccola quantità di memoria e non supporta molto più del minimo previsto /bin/sh. Su RHEL, /bin/shè bash, che è più lento e utilizza più memoria ma ha più funzionalità. Una di queste funzionalità è l' ==operatore per la [sintassi condizionale. Dash supporta [, che è una funzione sh di base, ma non ha l' ==operatore che è un'estensione bash (e ksh e zsh).

Puoi cambiare il tuo sistema usando bash. Su Ubuntu, /bin/shc'è un collegamento simbolico a dash. Puoi invece renderlo un collegamento simbolico bash. Le versioni attuali di Debian e Ubuntu (e derivati) rendono questa opzione di installazione di dash. Per cambiarlo, corri

sudo dpkg-reconfigure dash

e rispondi "sì" per mantenere il trattino come /bin/sho "no" per passare a bash.

Puoi continuare con bash /bin/sh, ma renderà il tuo sistema un po 'più lento. È anche ipotizzabile che alcuni script di sistema siano incompatibili con bash, sebbene ciò sia improbabile poiché bash è principalmente un superset di dash.


Per le distribuzioni che non hanno un'interfaccia tra cui scegliere tra le implementazioni /bin/sh, ecco come passare a bash.

sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh

Tieni un terminale aperto e verifica che dopo puoi ancora eseguire alcuni shscript. Se confondi questo comando, renderai il tuo sistema inutilizzabile. (A proposito, il motivo per cui ho usato i comandi multipli sopra piuttosto che quelli semplici sudo ln -sf bash /bin/shè che ln -sfnon è atomico. Nel caso in cui è improbabile che il tuo computer si sia arrestato in modo anomalo durante questa operazione, dovrai ripristinarlo da un supporto di ripristino. Al contrario, mvè atomico.)

Per ripristinare il trattino come /bin/sh:

sudo ln -s dash /bin/sh.dash
sudo mv /bin/sh.dash /bin/sh

Nota che se sh è /bin/bashdi default nella tua distribuzione, il passaggio a dash potrebbe causare errori negli script, poiché bash ha molte più funzioni rispetto a dash. Gli script Bash dovrebbero iniziare con #!/bin/bash, e gli script che iniziano con #!/bin/shnon dovrebbero usare funzionalità specifiche di bash, ma le distribuzioni fornite con bash /bin/shpotrebbero utilizzare funzionalità specifiche di bash in #!/bin/shscript specifici per quella distribuzione (va bene finché non ci si aspetta che gli utenti può passare al trattino come /bin/she non ci sono aspettative che questi script funzionino su un'altra distribuzione).


Secondo la mia opinione non così umile, se qualche script fallisce quando /bin/shè Bash, è un bug nel sistema (il pacchetto con lo script), o nella modalità di Bash sh. Come dice Stephen, il sistema consente esplicitamente di /bin/shtornare a Bash, tramite dpkg-reconfigure. È anche menzionato come una possibilità nella wiki di Ubuntu su questo argomento: wiki.ubuntu.com/DashAsBinSh
ilkkachu

5
@ilkkachu Sì, se uno script fallisce se /bin/shè bash, è un bug. Tuttavia, si verificano bug. Consiglio di attenersi al valore predefinito se non sei in grado e disposto a diagnosticare tali bug perché altre persone lo hanno testato per te. Ho usato dash come /bin/shprima che fosse ufficialmente supportato su Debian, ma questo era un rischio che prendevo, sapendo che sarei stato in grado di farcela se fosse successo qualcosa.
Gilles 'SO- smetti di essere malvagio'

Si noti che i collegamenti simbolici sovrascritti manualmente verranno ripristinati su qualsiasi configurazione archiviata debconfal successivo dashaggiornamento; è vero che ciò non accadrà spesso (se non del tutto, in una data versione) per i sistemi che eseguono Debian stable.
Stephen Kitt,

36

Per passare sha bash(anziché a dashquello predefinito), riconfigurare dash(sì, è in qualche modo contro-intuitivo):

sudo dpkg-reconfigure dash

Questo ti chiederà se vuoi dashessere la shell di sistema predefinita; rispondi "No" ( Tabquindi Enter) e bashdiventerà invece il valore predefinito ( ovvero /bin/sh indicherà /bin/bash).


1
La tua soluzione è davvero la più ragionevole, ma ho accettato un'altra risposta a causa delle descrizioni dettagliate che chiariscono il problema. Ci scusiamo per l'inconveniente.
Googlebot,

@Googlebot non è necessario scusarsi, scegliere la risposta accettata è il privilegio del richiedente. E ho ottenuto un distintivo d'oro da esso ;-).
Stephen Kitt,
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.