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 を元に戻す場合、これは問題にならないと考えました。しかし、私は今すべてのテーブルの1行しか持っていないので、間違っていました.
私の現在のコード:

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 変数をエコーし​​ようとすると、1 行に 1 つのテーブルが表示されますが、すべてのテーブルを含む $TABLE 変数で for ループが 1 回だけ実行されます。

よろしく
お願いしますキロ

4

1 に答える 1

6

forの代わりにwhileループを使用します。

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

...ループ内に変数を設定し、ループの終了後にそれらを使用可能にする必要がある場合を除きます。これにより、whileループがパイプラインの一部になるため、サブシェルで実行され、変数などはメインシェルに転送されません。メインシェルでループを実行する必要がある場合は、標準のパイプの代わりにbashのプロセス置換機能を使用できます。

while read TABLE
do
    ...
done < <(mysql -u user -ppassword -e "show tables" dbname | tail -n +2)
于 2012-06-08T15:14:10.740 に答える