I have this in a bash script
DAY2="20130605"<Cr>
echo "This is yesterday date:"$DAY2"end"
Why is the output the following? It seems as though there is a carriage return in DAY2
but where is it coming from?
ends is yesterday date:20130605
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityCarriage return puts the cursor back to the beginning of the line. Your output string is:
This is yesterday date:20130605<Cr>end
Except, when the terminal hits the <Cr>
it returns the cursor to the beginning of the line and overwrites the characters that are there.
In other words, "Thi" gets replaced with "end", producing:
ends is yesterday date:20130605
To do what you appear to be trying to do your script should look something like this:
variable="text"
echo "Some sentence $variable"
Which will output
Some sentence text
IF there are stray carriage returns they should show up as ^M
in vi
(as Bruce said)
Solution 1
The best way to remove carriage returns or other non-printing characters is with the tr
command with the -d
option, which deletes any instance of a single character, with \r
which is the escape sequence for carriage return:
tr -d '\r'
This will remove all carriage returns. Run it on the script to remove all instances of carriage returns, then overwrite the original script file:
tr -d '\r' yourscript.bash > temp
mv temp yourscript.bash
Solution 2
or while in vi
with the script open enter:
:%s/\r//g
:wq
To remove the carriage returns within the document then save it.
Assuming <Cr>
represents a carriage return, remove the carriage return from the end of the first line. Here's a one-liner to do it for you:
sed -i '1s/\r//' script.sh
To see the carriage returns in your script, run the following.
od -c script.sh | grep --color=yes '\r'
Use vi
or vim
to look at the bash script in question. You should see any stray carriage returns as '^M' (caret, em) two-character sequences. Use hjkl to move cursor over the carriage returns, hit 'x' to delete them, then ":wq" to get out of vi
.
My guess would be that a stray carriage return got into the file when someone moved the file to a Windows machine, edited it with Notepad or Wordpad, and then moved it back to linux.
In shell scripts, CR is an ordinary character, not whitespace like in many other languages. That line DAY2="20130605"<Cr>
sets DAY2
to a 9-character string, it's equivalent to DAY2=$'20130605\r'
. The echo
line is equivalent to echo $'This is yesterday date:20130605\rend'
. The CR character ($'\r'
) moves the cursor to the beginning of the line, thus (¡
indicates the cursor location):
This is yesterday date:¡ #after printing up to date:
This is yesterday date:20130605¡ #after printing up to 20130605
¡This is yesterday date:20130605 #after printing the CR
end¡s is yesterday date:20130605 #after printing end
Remove the CR from the script.
Exactly how that carriage return came to be is hard to say.
If the script was generated by another script or an application it could be a bug or intended mishap.
Most likely you or whomever edited the file has unintentionally pressed a key combination causing CR
to be inserted.
Examples:
vim :
Ctrl-v Ctrl-memacs:
Ctrl-q Ctrl-mThere are other characters that can cause trouble as well, e.g. no-break-space in code etc. This usually cause weird bugs when running scripts or compiling code.
I normally use vim
and frequently set (have a key-combination to toggle it):
match Error /[^ -~\t]/
That is: highlight everything but <space>
to ~
in ASCII and tab
with Error
, typically white on red etc.
For code files I usually have this is set on by default.
In the terminal carriage return normally causes the cursor to move to start of line, thus any print after it is overwriting any existing text on that line until a line feed comes along.
E.g.:
#!/bin/bash
for i in {1..100}; do
printf "We are now at %3d%%\r" "$i"
sleep .1
done
printf "\nAll done.\n"
\r
, when using printf
result in <CR>
or Carriage Return.
\n
, when using printf
result in <LF>
or Line Feed.