0

I have a bash script that pulls a bit of text from an external MySQL database. Most of the times it are 4 lines, each one on his own line. This text (in total) has to be placed into a file. The script now pulls the information from the MySQL database, puts it in a variable. Then I echo it in a file:

echo -ne $variable > file

The problem is that the 'n' gets also printed/echo'ed to the file. Like this:

here is sentence number 1
nthere is number 2
nals here comes number 3
nlast but not least number 4

somehow there is a kind of new-line that is printed and I need to have the text without the 'n'.

EDIT 1 - copy of the Bash script:

#!/bin/bash

DBHOST='xx.xxx.xx.xxxx'
DBUSER='xxxxxx'
DBPASS='xxxxxx'
DBNAME='xxxxxx'

mysql -N -u$DBUSER -p$DBPASS -h$DBHOST -D$DBNAME -e "SELECT id,vhost FROM test;" | while read id vhost;
do
echo -ne $vhost > vhost
done

For obvious reasons I removed the database details.

EDIT 2 - I am using the following Bash and Ubuntu version:

Ubuntu: 12.04.2 Bash: 4.2.25

HopelessN00b
  • 53,385
  • 32
  • 133
  • 208
Jona Koudijs
  • 75
  • 3
  • 10

2 Answers2

4

The first and biggest problem is that you need quotes around your variable.

echo -ne "$variable" > file

Then I would try omitting one or both of the -e and -n. Ideally, printf should be used instead of echo since it's more portable.

Edit:

Thanks for showing additional parts of your script which are essential in diagnosing the issue.

If the vhost field may contain the literal string "\n" (backslash-n not a newline) in its contents then you must use the -r option with read if you want to preserve the backslash. In fact, you should almost always use the -r anyway out of habit. By preserving the backslash, the -e option of echo will interpret the literal "\n" as the escape sequence which represents a newline and output a newline instead of an "n".

mysql -N -u$DBUSER -p"$DBPASS" -h$DBHOST -D$DBNAME -e "SELECT id,vhost FROM test;" | 
while read -r id vhost;
do
    echo -en "$vhost"
done > vhost

You can move the redirection to the end of the while loop to avoid repeatedly opening and closing the output file and overwriting the contents on each iteration. You can use the trailing pipe also as a line continuation character to aid in readability.

The habits I mentioned earlier, including always quoting a variable for output, should be well ingrained. They prevent unexpected behavior at inopportune times. Probably the best reference to use in learning these habits is Greg Wooledge's BashFAQs and other pages at that site.

Dennis Williamson
  • 60,515
  • 14
  • 113
  • 148
  • I already tried that. Probably a habbit that I did not include the quotes. I tested it again a few minutes ago just to be sure, it still includes the 'n'. – Jona Koudijs Jun 05 '13 at 18:59
  • It also makes no difference if I dont use the -e, dont use the -n or dont use them both. If I would like to use printf instead, what kind of command I would create? – Jona Koudijs Jun 05 '13 at 19:07
  • pipe it into tr. echo "$variable" | tr -d '\n' > file – Sirex Jun 05 '13 at 21:11
  • @JonaKoudijs: Please see my edited answer. – Dennis Williamson Jun 06 '13 at 02:18
  • Thank you very much for your answer. I have been playing around a little more but it still doesn't work. If I add the -r after 'read' I get '\n' after every line instead of 'n'. – Jona Koudijs Jun 06 '13 at 07:50
  • @JonaKoudijs: If your fields contain "\n" then `echo -e` will interpret that as newlines. There is something you're not revealing. Please post an example of the output of the mysql `SELECT` statement which has not been passed through the `while` loop. – Dennis Williamson Jun 06 '13 at 08:13
  • @JonaKoudijs: One other thing I wanted to mention is that you should use a my.conf file to contain your credentials rather than passing the password as a command line argument for security reasons. Otherwise somebody may be able to see the password using `ps`. – Dennis Williamson Jun 06 '13 at 08:16
  • @DennisWilliamson Thank you for reaction. It works now! I don't know exactly what I did that triggered it. Maybe I opened the wrong test file, because I did not really change anything. It is now as you said. Thanks again! – Jona Koudijs Jun 06 '13 at 08:33
0
  1. You probably want to append (>>), not overwrite (>).
  2. Are you sure that removing -n doesn't work?
  3. Why not:

    mysql -N -u$DBUSER -p$DBPASS -h$DBHOST -D$DBNAME -e "SELECT vhost FROM test;" > vhost

quanta
  • 50,327
  • 19
  • 152
  • 213
  • I want to overwrite the file not append it. I am 100% positive. The script will be bigger en there a couple of other things that will get included in the loop part. So this way is better for me. – Jona Koudijs Jun 06 '13 at 07:56