web-dev-qa-db-ja.com

gnuparallelを使用してrsync呼び出しを並列化する

以下に示すように、gnu-parallelを使用してrsync呼び出しを並列化しようとしています。しかし、以下のスクリプトを実行すると、何もコピーされないように見えます。しかし、私は多くのrsyncプロセスを見ています(ps aux | grep rsync)実行中なので、ここで何が問題なのかわからない:

export PRIMARY=/data01/test_primary
export SECONDARY=/data02/test_secondary
export dir3=/bat/data/snapshot/20180227
PRIMARY_FILES=(685 959 682 679 688 651 909 906 657 881 884 878 853 707 847)
SECONDARY_FILES=(950 883 887 890 1001 994 997 1058 981 833)

export LOCATION_1="machineA"
export LOCATION_2="machineB"
export LOCATION_3="machineC"

do_Copy() {
  el=$1
  PRIMSEC=$2
  rsync -az golden@"$LOCATION_1":"$dir3"/proc_"$el"_5.data "$PRIMSEC"/. || rsync -az golden@"$LOCATION_2":"$dir3"/proc_"$el"_5.data "$PRIMSEC"/. || rsync -az golden@"$LOCATION_3":"$dir3"/proc_"$el"_5.data "$PRIMSEC"/. || exit 1
}
export -f do_Copy
parallel -j 5 do_Copy {} $PRIMARY ::: ${PRIMARY_FILES[@]} &
parallel -j 5 do_Copy {} $SECONDARY ::: ${SECONDARY_FILES[@]} &
wait

echo "All copied."

私がここでやっている何か問題はありますか?

3
david

定義したdo_Copy関数で引数を誤って処理しています。シェルスクリプトで位置引数を処理する場合は、特に注意してください。コードは、最後のコマンドで配列から1つの引数を残すだけです。

関数内の引数の完全なリストとして$@を使用する必要があります。

do_Copy() {
  (( "$#" )) || { printf 'insufficient args supplied' >&2 ; return 2; }

  el="$1"; shift
  PRIMSEC="$@"

  rsync -az golden@"$LOCATION_1":"$dir3"/proc_"$el"_5.data "$PRIMSEC"/. || rsync -az golden@"$LOCATION_2":"$dir3"/proc_"$el"_5.data "$PRIMSEC"/. || rsync -az golden@"$LOCATION_3":"$dir3"/proc_"$el"_5.data "$PRIMSEC"/. || exit 1
}

配列を呼び出すときに変数を引用します

export -f do_Copy
parallel -j 5 do_Copy {} "$PRIMARY" ::: "${PRIMARY_FILES[@]}" &

$1を関数に格納すると、最初にshiftを呼び出すと、残りの位置引数は、最初に格納する予定だった"$@"の下で使用できます。

1
Inian