This question already has an answer here:
-
Are shell scripts sensitive to encoding and line endings?
2 answers
I have a simple shell script I copied from a working script. It works if I copy-paste it to a terminal:
if true
then
true
fi
However, when I run the script with bash myscript
, I get various syntax errors as if some of the keywords are missing.
myscript: line 4: syntax error near unexpected token `fi\'
, as if then
isn\'t there.
myscript: line 6: syntax error: unexpected end of file
, as if fi
isn\'t there.
myscript: line 4: syntax error near unexpected token `$\'\\r\'
.. what?
Why does this happen in this particular script, but not on my command line or in the script I copied from?
TL;DR: Your script has Windows style CRLF line endings, aka \\r\\n
.
Convert to Unix style \\n
by deleting the carriage returns.
How do I check if my script has carriage returns?
They\'re detectable as ^M
in the output of cat -v yourscript
:
$ cat -v myscript
if true^M
then^M
true^M
...
How do I remove them?
Set your editor to save the file with Unix line endings, aka \"line terminators\" or \"end-of-line characters\", and resave it.
You can also remove them from a command line with dos2unix yourscript
or cat yourscript | tr -d \'\\r\' > fixedscript
.
Why do carriage returns cause syntax errors?
The carriage return character is just another character to bash. then
is not the same as then\\r
, so bash doesn\'t recognize it as a keyword and assumes it\'s a command. It then keeps looking for a then
and fails
If there happens to be a trailing space after then
, you get a similar problem for fi
.