2012-06-08 50 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)