Bash循环中的多行输出命令

3

我需要编写一个小型的多线程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"

我尝试使用echo命令输出$TABLES变量的值,却每行输出一个表格名称。但是for循环只执行了一次,$TABLE变量包含了所有的表格名称。

提前致谢
kiro


在Bash中将IFS设置为换行符:IFS=$'\n' - Dennis Williamson
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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接