TL;DR: Your script or data has Windows style CRLF line endings.
Convert to Unix style by deleting the carriage returns.
How do I check if my script or data has carriage returns?
They're detectable as ^M
in the output of cat -v yourscript
:
$ cat -v myscript
ls -l myfile^M
If your script doesn't have them, your data might -- especially if reading from ini/csv files or curl
:
hostname=$(curl https://example.com/loginhost.txt)
ssh "$hostname" # Shows strange error
echo "$hostname" | cat -v # Shows myhost^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
.
If found in your data, you can pipe your source through tr -d '\r'
:
hostname=$(curl https://example.com/loginhost.txt | tr -d '\r')
Why do carriage returns cause strange error messages?
The "carriage return" character, aka CR or \r
, causes the cursor to move to the start of the line, and continue printing from there. In other words, it starts overwriting the line from the start. This is why they wrap strangely:
Intended: ssh: Could not resolve hostname myhost\r: Name or service not known
Written: ssh: Could not resolve hostname myhost\r
Overwritten: : Name or service not known
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Result: : Name or service not knownname myhost