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.sh
uit.
U heeft hoogstwaarschijnlijk een regelterugloop of een no-break spatie in uw bestand. cat -v
toont ze respectievelijk als ^M
en 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):
TABS
geconverteerd naarSPACES
- voer
dos2unix
uit 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.sh
gebruiken 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 sp
staat voor spatie, de ht
staat voor tab, de cr
staat voor <CR>
en de nl
staat voor <LF>
. Merk op dat alle regels eindigen op cr
gevolgd door een nl
-teken.
Je kunt ook cat -v test.sh
gebruiken als je cat
-commando de parameter -v
nodig heeft.
Als je dos2unix
op 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 os2unix
of tr
te 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 cat
geen 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 else
verklaring. Na het opnieuw schrijven van de voorwaarden, kwam de fout ‘in de buurt van gedaan’ weg.