使用命令的多行输出进行Bash for循环

时间:2012-06-08 12:28:17

标签: bash for-loop mysqldump multiline

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

提前致谢
基罗

1 个答案:

答案 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)