Reputation: 85
I have to write a small multithreaded mysqldump script for our database and I got some problems because of a single table containing a space.
My first attempt was quite easy:
for TABLE in `mysql -u user -ppassword -e 'show tables;' dbname`
do
while [ 1 ]
do
if [ `jobs -r | wc -l` -lt $MAXTHREADS ]
then
break
else
sleep 1
fi
done
mysqldump -u user -ppassword dbname $TABLE
done
Unfortunetely there was a table which contained a space. I googled a little bit for using the for loop with multiline output from commands and changing the $IFS variable was a common solution. So I changed it to \n\b (somehow $IFS was empty when I only used \n) but that was a bad idea because it caused the mysql commands to not work anymore.
I thought that this shouldn't be a problem when I get the tables beforehand and change the $IFS back everytime I use mysqldump in the for loop. But again I was mistaken as I only have one line of all tables now.
My current code:
TABLES=$(mysql -u user -ppassword -e "show tables" dbname | tail -n +2)
OIFS="$IFS"
AIFS=$(echo -en "\n\b")
IFS="$AIFS"
for TABLE in "$TABLES"
do
IFS="$OIFS"
while [ 1 ]
do
if [ `jobs -r | wc -l` -lt $MAXTHREADS ]
then
break
else
sleep 1
fi
done
mysqldump -u user -ppassword dbname $TABLE
IFS="$AIFS"
done
IFS="$OIFS"
When I try to echo the $TABLES variable I get one table per line, but the for loop is only running once with the $TABLE variable containing ALL the tables.
Thanks in advance
kiro
Upvotes: 4
Views: 6391
Reputation: 125838
Use a while loop instead of for:
mysql -u user -ppassword -e "show tables" dbname | tail -n +2 | while read TABLE
do
...
done
...unless you need to set any variables inside the loop and have them available after the loop exits. Since this makes the while loop part of a pipeline, it runs in a subshell, and variables and such don't transfer to the main shell. If you need the loop to run in the main shell, you can use bash's process substitution feature instead of a standard pipe:
while read TABLE
do
...
done < <(mysql -u user -ppassword -e "show tables" dbname | tail -n +2)
Upvotes: 6