Problemi con Bash 4.2.45 su Ubuntu

Sto utilizzando un server remot che esegue Ubuntu 13.10 con Bash 4.2.45 installato. Il mio sistema domestico è OS X Mavericks con Bash 3.2.51 (Darwin build) installato. Non ho usato bash molto in passato, ma ho lavorato su uno script abbastanza grande e ho notato alcune cose che erano strano circa la versione installata sul server remoto.

Prendi uno script semplice per esempio:

#!/bin/sh read n if ((n > 10)); then echo "Number is pretty big" else echo "NUMBER IS WEAK AND SMALL" fi 

Mentre sotto bash 3.2.51 riconosce l'espressione e funziona sotto la bash 4 su Ubuntu, lancia un errore strano:

 script.sh: 5: script.sh: n: not found 

Ma non solo ((…)) non vengono riconosciute ma a volte le variables e altre dichiarazioni logiche. Come principiante di bash è molto confusa e ho voluto chiedere cosa posso fare per questo. Posso modificare le regole di syntax? O solo downgrade il server remoto in una versione 3.xy? Qualsiasi aiuto è apprezzato.

Quando ho letto la tua domanda sono rimasto sorpreso dal tuo comportmento, quindi ho deciso di riprodurlo rapidamente, quindi ho installato un nuovo Ubuntu 13.10 VM con Bash versione 4.2.45.

Una volta fatto, sono riuscito a riprodurre il comportmento che descrivi.

Dopo ulteriori indagini, sembra che devi sostituire #!/bin/sh con #!/bin/bash per far funzionare.

Modifica:

Per avviare lo script:

  • bash script.sh e ./script.sh functionranno.
  • sh script.sh non funziona.

Supponendo di avere #!/bin/bash alla prima row

Spero che functionrà per te!

Non utilizzi affatto la Bourne Again Shell.

È un errore ipotizzare che /bin/sh sia qualcosa di più di una shell conforms a POSIX. (Anche se è stato bash, quando bash viene invocato come sh esso modifica subtly il suo comportmento.) Su Ubuntu, /bin/sh ora è predefinito per Debian Almquist Shell, che è un shell diverso – uno dei molti shell (Thompson, Bourne , Bourne Again, Almquist, Korn, Z, Friendly Interactive, C, Tenex C, BusyBox, Norme conforms Ordinarie, …) che si possono trovare sui sisthemes Unix e Linux. L'interruttore di /bin/sh da Bourne Again a Debian Almquist ha migliorato la velocità di avvio di sisthemes Debian e Ubuntu, che eseguono molti script di shell come parte del process di avvio.

Se si vuole veramente utilizzare bashisms come (()) nel tuo script, impostare esplicitamente /bin/bash come interpnetworking di script nel suo #! linea.

Al contrario, se si desidera specificare /bin/sh come interpnetworking di script in sisthemes diversi come Mac OS e Linux, allora si attacca rigorosamente solo a quello che è conforms a POSIX.

Ulteriori letture

  • spingere come /bin/sh . Ubuntu wiki.
  • spingere come /bin/sh . Debian wiki.
  • " 6.11 modalità bash POSIX ". Bash Reference manaual . Progetto GNU.
  • bashismi . Greg's wiki.
  • Shell Command Language . IEEE Std 1003.1. Edizione 7. Il gruppo aperto.

n è una variabile, quindi è necessario riferirlo utilizzando un "$":

 #!/bin/sh read n if (($n > 10)); then echo "Number is pretty big" else echo "NUMBER IS WEAK AND SMALL" fi