我必须为我们的数据库编写一个小的多线程mysqldump脚本,因为一个包含空格的表,我遇到了一些问题。
我的第一次尝试很简单:
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
不幸的是,有一张桌子,里面有一个空间。我用谷歌搜索了一下使用for循环和命令的多行输出,并且更改$ IFS变量是一种常见的解决方案。所以我把它更改为\ n \ b(当我只使用\ n时,某种方式$ IFS是空的)但这是一个坏主意,因为它导致mysql命令不再起作用。
我认为当我事先得到表并且每次在for循环中使用mysqldump时更改$ IFS时,这应该不是问题。但我又错了,因为我现在只有一行所有表格 我目前的代码:
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"
当我尝试回显$ TABLES变量时,每行得到一个表,但for循环只运行一次,包含所有表的$ TABLE变量。
提前致谢
基罗
答案 0 :(得分:4)
使用while循环而不是:
mysql -u user -ppassword -e "show tables" dbname | tail -n +2 | while read TABLE
do
...
done
...除非你需要在循环中设置任何变量并在循环退出后使它们可用。因为这使得while循环成为管道的一部分,所以它在子shell中运行,而变量等不会转移到主shell。如果您需要在主shell中运行循环,则可以使用bash的进程替换功能而不是标准管道:
while read TABLE
do
...
done < <(mysql -u user -ppassword -e "show tables" dbname | tail -n +2)