2

我必须为我们的数据库编写一个小的多线程 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 变量包含所有表。

在此先感
谢基罗

4

1 回答 1

6

使用 while 循环代替 for:

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)
于 2012-06-08T15:14:10.740 回答