2012-06-08 51 views
1

我必须为我们的数据库编写一个小型多线程mysqldump脚本,并且由于包含一个空格的单个表,我遇到了一些问题。Bash for循环与命令的多行输出

我第一次尝试是很容易:

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有其中载有空间的表。为了使用for循环和命令中的多行输出,我改了一点点,并且改变$ IFS变量是一个常见的解决方案。所以我将它改为\ n \ b(当我仅使用\ n时$ IFS是空的),但这是一个坏主意,因为它导致mysql命令不再工作。

我认为这应该不会是一个问题,当我事先得到表并改变$ IFS每次我在for循环中使用mysqldump。但是我又错了,因为现在我只有一排桌子。
我当前的代码:

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" 

当我尝试呼应$表变量,我得到每行一个表,但是for循环仅包含所有表的$表变量运行一次。

在此先感谢
基罗

+0

要设置'IFS'在猛砸换行:'IFS = $“\ n” ' –

回答

4

使用while循环,而不是为:

mysql -u user -ppassword -e "show tables" dbname | tail -n +2 | while read TABLE 
do 
    ... 
done 

...除非你需要设置循环内的任何变量,并让他们退出循环后可用。由于这使得pipeline成为while循环的一部分,所以它在子shell中运行,并且变量等不会传递到主shell。如果你需要循环在主shell中运行,你可以使用,而不是一个标准管bash的进程替换功能:

while read TABLE 
do 
    ... 
done < <(mysql -u user -ppassword -e "show tables" dbname | tail -n +2)