3

I have a text file with a list of Mercurial repositories in it, in the form:

IDE
Install
InstallShield

I'm writing a bash script to clone/pull/update all the repositories based on the text file. Right now I'm just echoing before I do any actual cloning. If I do:

while read line; do
    echo "hg clone" ${MASTER_HG}/${line};
done < Repos.txt

The output is as expected:

hg clone /media/fs02/IDE
hg clone /media/fs02/Install
hg clone /media/fs02/InstallShield

However, if I do:

while read line; do
    echo "hg clone" ${MASTER_HG}/${line} ${REPOROOT}/${line};
done < Repos.txt

The output is:

/var/hg/repos/IDE02/IDE 
/var/hg/repos/Installnstall
/var/hg/repos/InstallShieldShield

It seems to be replacing the beginning of the string with the end of the string. Is there some kind of character overflow or something going on? My apologies if this is a dumb question, but I'm a relative noob for bash.

3
  • 2
    Carriage returns? CRLF endings in Repos.txt? Commented Jul 31, 2013 at 20:48
  • 4
    CRLF is the new square root of all evil. Commented Jul 31, 2013 at 20:50
  • 1
    +1 for "a relative noob" with some actual code. Commented Jul 31, 2013 at 20:56

2 Answers 2

6

Your file has DOS line endings; the \r at the end of $line causes the cursor to return to the beginning of the line, which only affects your output when $line is not the last thing being printed before the newline. You should remove them with something like dos2unix.


You can use something similar to Perl's chomp command to remove a trailing carriage return, if one is present:

# $'\r' is bash-only, but easy to type. For POSIX shell, you'll need to find
# someway of entering ASCII character 13; perhaps Control-V Control-M
line=${line%$'\r'}

Useful if, for whatever reason, you can't (or don't want to) fix the input before reading it.

Sign up to request clarification or add additional context in comments.

2 Comments

Good grief. You're right. Thank you! I should have noticed the dos flag at the bottom of my editor. I'm embarrassed to say how long that stumped me.
@ChrisBush I'm sure it's happened to all of us at least once.
1

From the looks of it, ${REPOROOT} might already include ${line}, try echoing ${REPOROOT} by itself and see what you get.

3 Comments

Thanks for the answer. It turned out to be DOS-esque carriage returns like chepner suggested.
Ah, I see now. I wrote my answer before you edited the formatting, so I didn't notice that some of the characters were missing, rather than simply repeated the ${line} value... capital i = I != l = lowercase L
That was my fault. Thanks to Ruben for highlighting the output.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.