/ / BASH Errore di sintassi vicino al token imprevisto 'done' - bash

BASH Errore di sintassi vicino al token imprevisto 'done' - bash

Qualche idea su quale potrebbe essere il problema?

Il mio codice è:

#!/bin/bash
while :
do
echo "Press [CTRL+C] to stop.."
sleep 1
done

Lo ha salvato come .sh e ha eseguito bash file.sh

CentOS 6 a 32 bit

Qual'è il problema? La prima volta che uso MAI, ne ho bisogno per un semplice ciclo infinito su qualcosa.

risposte:

19 per risposta № 1

Correre cat -v file.sh.

Molto probabilmente hai un ritorno a capo o uno spazio senza interruzioni nel tuo file. cat -v li mostrerà come ^M e M-BM- o M- rispettivamente. Allo stesso modo mostrerà qualsiasi altro strano personaggio che potresti avere nel tuo file.

Rimuovere le interruzioni di riga di Windows con

tr -d "r" file.sh > fixedfile.sh

8 per risposta № 2

Stavo ricevendo lo stesso errore su Cygwin; Ho fatto quanto segue (uno di essi lo ha risolto):

  1. convertito TABS a SPACES
  2. corse dos2unix sul .(ba)sh file

4 per risposta № 3

Qual è l'errore che stai ottenendo?

$ bash file.sh
test.sh: line 8: syntax error: unexpected end of file

Se ottieni questo errore, potresti avere terminazioni di riga sbagliate. Usa Unix <LF> alla fine del file mentre Windows utilizza <CR><LF>. Quello <CR> il personaggio viene interpretato come un personaggio.

Puoi usare od -a test.sh per vedere il invisibile caratteri nel file.

$ od -a test.sh
0000000    #   !   /   b   i   n   /   b   a   s   h  cr  nl   #  sp  cr
0000020   nl   w   h   i   l   e  sp   :  cr  nl   d   o  cr  nl  sp  sp
0000040   sp  sp   e   c   h   o  sp   "   P   r   e   s   s  sp   [   C
0000060    T   R   L   +   C   ]  sp   t   o  sp   s   t   o   p   "  cr
0000100   nl  sp  sp  sp  sp   s   l   e   e   p  sp   1  cr  nl   d   o
0000120    n   e  cr  nl
0000124

Il sp sta per spazio, il ht sta per scheda, il cr sta per <CR> e il nl sta per <LF>. Nota che tutte le linee finiscono con cr seguito da a nl carattere.

Puoi anche usare cat -v test.sh se tuo cat il comando prende il -v parametro.

Se hai dos2unix sulla tua scatola, puoi usare quel comando per correggere il tuo file:

$ dos2unix test.sh

2 per risposta № 4

A volte questo errore si verifica a causa di caratteri CR inattesi nel file, in genere perché il file è stato generato su un sistema Windows che utilizza terminazioni di linea CR. Puoi risolvere questo problema eseguendo os2unix o tr, per esempio:

tr -d "

Ciò rimuove qualsiasi carattere CR dal file.


1 per risposta № 5

Apri un nuovo file chiamato foobar

nano -w foobar

Script di input

 #!/bin/bash
while [ 0 = 0 ]; do
echo "Press [CTRL+C] to stop.."
sleep 1
done;

Esci e salva

CTRL+X poi Y e accedere

Imposta script eseguibile ed esegui

chmod +x foobar
./foobar

1 per risposta № 6

Potrebbe aiutare qualcun altro: ho riscontrato lo stesso tipo di problemi mentre avevo fatto alcuni "copia-incolla" da un documento di Microsoft Word, dove ho preso appunti, ai miei script di shell.

Riscrivendo, manualmente, lo stesso identico codice nello script ha appena risolto questo problema.

All'inizio era abbastanza incomprensibile, pensoI caratteri nascosti di Word e / o la formattazione erano il problema: ovvio ma non visibile ... Ho perso circa un'ora su questo (non sono un esperto di shell, come puoi immaginare ...)


0 per risposta № 7

Modifica il tuo codice in qualsiasi ambiente Linux, quindi non dovrai affrontare questo problema notepad qualsiasi spazio prendilo come ^ M.


0 per risposta № 8

Ho esattamente lo stesso problema di cui sopra e ho presotutto il giorno per scoprire che non mi piace il mio approccio a newline, invece ho riutilizzato lo stesso codice con un approccio semi-colon. Ad esempio il mio codice iniziale che utilizza la nuova riga (che ha generato lo stesso errore del tuo):

Y=1
while test "$Y" -le "20"
do
echo "Number $Y"
Y=$[Y+1]
done

E usando il codice con approccio a punto e virgola con meraviglia lavorata:

Y=1 ; while test "$Y" -le "20"; do echo "Number $Y"; Y=$[Y+1] ; done

Ho notato che lo stesso problema si verifica anche per altri comandi che utilizzano l'approccio newline, quindi penso che resterò fedele all'uso del punto e virgola per il mio codice futuro.


0 per risposta № 9

C'è un modo per ottenere questo problema senza problemi di newline (almeno, nella mia shell, che è GNU bash v4.3.30):

#!/bin/bash
# foo.sh

function foo() {
echo "I am quoting a thing `$1" inside a function."
}

while [ "$input" != "y" ]; do
read -p "Hit `y" to continue: " -n 1 input
echo
done

foo "What could possibly go wrong?"
$ ./foo.sh
./foo.sh: line 11: syntax error near unexpected token `done"
./foo.sh: line 11: `done"

Questo perché bash espande i backtick all'interno di stringhe tra virgolette (vedi il manuale di bash su citando e sostituzione di comando), e prima di trovare un apice di corrispondenza, interpreterà le doppie virgolette aggiuntive come parte della sostituzione di comando:

$ echo "Command substitution happens inside double-quoted strings: `ls`"
Command substitution happens inside double-quoted strings: foo.sh
$ echo "..even with double quotes: `grep -E "^foo|wrong" foo.sh`"
..even with double quotes: foo "What could possibly go wrong?"

È possibile aggirare questo evitando i backtick nella stringa con una barra rovesciata o utilizzando una stringa con quotatura singola.

Non sono davvero sicuro del motivo per cui questo fornisce solo un messaggio di errore, ma penso che abbia a che fare con la definizione della funzione:

#!/bin/bash
# a.sh

function a() {
echo "Thing"s `quoted""
}
a
while true; do
echo "Other `quote""
done
#!/bin/bash
# b.sh

echo "Thing"s `quoted""
while true; do
echo "Other `quote""
done
$ ./a.sh
./a.sh: line 10: syntax error near unexpected token `done"
./a.sh: line 10: `done"
$ ./b.sh
./b.sh: command substitution: line 6: unexpected EOF while looking for matching `""
./b.sh: command substitution: line 9: syntax error: unexpected end of file
Thing"s quote"
./b.sh: line 7: syntax error near unexpected token `done"
./b.sh: line 7: `done"