BASH-syntaxisfout bijna onverwacht token ‘klaar’

Enig idee van wat het probleem zou kunnen zijn?

Mijn code is:

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

Opgeslagen als .sh en uitgevoerd bash file.sh

CentOS 6 32-bits

Wat is het probleem? De eerste keer dat ik BASH OOIT gebruik, heb het nodig voor een eenvoudige oneindige lus op iets.


Antwoord 1, autoriteit 100%

Voer cat -v file.shuit.

U heeft hoogstwaarschijnlijk een regelterugloop of een no-break spatie in uw bestand. cat -vtoont ze respectievelijk als ^Men M-BM-of M-. Het zal op dezelfde manier alle andere vreemde tekens tonen die je in je bestand hebt gekregen.

Verwijder de regeleinden van Windows met

tr -d '\r' < file.sh > fixedfile.sh

Antwoord 2, autoriteit 27%

Ik kreeg dezelfde foutmelding op Cygwin; Ik heb het volgende gedaan (een van hen heeft het opgelost):

  1. TABSgeconverteerd naar SPACES
  2. voer dos2unixuit op het bestand .(ba)sh

Antwoord 3, autoriteit 15%

Wat is de foutmelding die je krijgt?

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

Als je die foutmelding krijgt, heb je mogelijk slechte regeleindes. Unix gebruikt <LF>aan het einde van het bestand, terwijl Windows <CR><LF>gebruikt. Dat <CR>-teken wordt geïnterpreteerd als een teken.

Je kunt od -a test.shgebruiken om de onzichtbaretekens in het bestand te zien.

$ 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

De spstaat voor spatie, de htstaat voor tab, de crstaat voor <CR>en de nlstaat voor <LF>. Merk op dat alle regels eindigen op crgevolgd door een nl-teken.

Je kunt ook cat -v test.shgebruiken als je cat-commando de parameter -vnodig heeft.

Als je dos2unixop je box hebt staan, kun je dat commando gebruiken om je bestand te repareren:

$ dos2unix test.sh

Antwoord 4, autoriteit 10%

Misschien iemand anders helpen: ik kwam dezelfde soort problemen tegen toen ik wat “copy-paste” had gedaan vanuit een Microsoft Word-document aan de zijkant, waar ik aantekeningen maakte, naar mijn shellscript(s).

Het handmatig herschrijven van exact dezelfde code in het script heeft dit zojuist opgelost.

In het begin was het nogal onbegrijpelijk, ik denk dat de verborgen tekens en/of opmaak van Word het probleem waren. Voor de hand liggend maar niet zichtbaar … Ik verloor ongeveer een uur hiermee (ik ben geen shell-expert, zoals je zou kunnen raden …)


Antwoord 5, autoriteit 10%

Soms gebeurt deze fout vanwege onverwachte CR-tekens in het bestand, meestal omdat het bestand is gegenereerd op een Windows-systeem dat CR-regel-eindes gebruikt. U kunt dit oplossen door os2unixof trte gebruiken, bijvoorbeeld:

TR -D ‘\ 015’ & LT; YESCRIPT.SH & GT; Newscript.SH

Hiermee verwijdert u CR-tekens uit het bestand.


Antwoord 6, Autoriteit 7%

Er is een manier waarop u dit probleem kunt krijgen zonder gemengde newline-problemen (tenminste, in mijn shell, die GNU bash v4.3.30) is:

#!/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'

Dit komt omdat Bash Backticks binnen dubbel geciteerde strings uitbreidt (zie de BASH-handleiding op Citeren en opdrachtvervanging ), en vóór het vinden van een bijpassende backtick, interpreteert eventuele extra dubbele aanhalingstekens als onderdeel van de opdrachtvervanging:

$ 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?"

Je kunt dit omzeilen door de backticks in je string te escapen met een backslash, of door een string met enkele aanhalingstekens te gebruiken.

Ik weet niet precies waarom dit slechts die ene foutmelding geeft, maar ik denk dat het te maken heeft met de functiedefinitie:

#!/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'

Antwoord 7, autoriteit 5%

Open nieuw bestand met de naamfoobar

nano -w foobar

Script invoeren

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

Afsluiten en opslaan

CTRL+Xdan Yen Enter

Stel het uitvoerbare script in en voer het uit

chmod +x foobar
./foobar

Antwoord 8, autoriteit 2%

Net soortgelijke problemen gehad en dit zijn twee afzonderlijke instanties en oplossingen die voor mij hebben gewerkt:

Geval 1.Kortom, had een spatie na het laatste commandoin mijn door nieuwe regels gescheidenfor-loop, bijv. (in de veronderstelling dat |hier de karaat vertegenwoordigt in een teksteditor die laat zien waar je schrijft), dit is wat ik zag toen ik rond het einde van de regel van de laatste opdracht in de lus klikte:

for f in $pathToFiles
do
   $stuff |
done

Let op de spatie vóór de karaat (voor zover ik weet, is dit iets dat catgeen optie heeft om visueel weer te geven (een manier waarop je kontesten is met iets zoals od -bc yourscript.sh)). De code wijzigen in

for f in $pathToFiles
do
   $stuff| <--- notice the carat shows no ending space before the newline
done

het probleem opgelost.

Geval 2.Gebruikte een pseudo-try-catch-blok voor de for-loop (zie https: //stackoverflow.com/a/22010339/8236733) leuk vinden

{
for f in $pathToFiles
do
   { $stuff } || { echo "Failed to complete stuff"; exit 255; }
done
} || { echo "Failed to complete loop"; exit 255; }

en blijkbaar hield bash niet van de geneste {}s. Wijzigen in

{
for f in $pathToFiles
do
   $stuff
done
} || { echo "Failed to complete loop"; exit 255; }

het probleem is in dit geval opgelost. Als iemand een van deze gevallen verder kan uitleggen, laat het me dan weten in de opmerkingen.


Antwoord 9, autoriteit 2%

Ik had hetzelfde probleem, maar opgelost.

Ik heb de volgende regel in .Bashrc

verwijderd

alias do="docker.exe" # this line caused the problem

Ik gebruik WSL (Windows Subsystem voor Linux)


Antwoord 10

Bewerk uw code in elke Linux-omgeving, dan zie je dit probleem niet. Als bewerken in Windows
Kladblok Elke ruimte neemt het als ^ m.


Antwoord 11

Ik heb precies hetzelfde probleem zoals hierboven en kostte me de hele dag om te ontdekken dat het niet van mijn newline-aanpak houdt. In plaats daarvan hergebruikt ik dezelfde code met semi-colon-benadering in plaats daarvan.
Bijvoorbeeld mijn eerste code met behulp van de newline (die dezelfde fout gooide als de jouwe):

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

en gebruik code met puntkomma-aanpak met bewerkte wonder:

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

Ik merk dat hetzelfde probleem optreedt voor andere opdrachten die ook gebruik maken van de newline-aanpak, dus ik denk dat ik aan het gebruik van puntkomma voor mijn toekomstige code blijven.


Antwoord 12

In mijn geval, wat het probleem veroorzaakte was een if elseverklaring. Na het opnieuw schrijven van de voorwaarden, kwam de fout ‘in de buurt van gedaan’ weg.

Other episodes