4

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

5 Answers 5

6

Carriage 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.

3

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'
1

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.

1

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.

0

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-m
  • emacs: Ctrl-q Ctrl-m
  • And many others.

There 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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .