5つのファイルを並列にコピーしようとしている次のシェルスクリプトがあります。私はmachineA
machineBとmachineCからファイルをコピーしようとして下のシェルスクリプトを実行しています。
ファイルが にない場合は必ず になけれmachineB
ばなりません。machineC
ここでは、GNU Parallelを使用して5つのファイルを並列にダウンロードしています。
#!/bin/bash
readonly PRIMARY=/tech01/primary
readonly FILERS_LOCATION=(machineB machineC)
readonly MEMORY_MAPPED_LOCATION=/techbat/data/be_t1_snapshot
PRIMARY_PARTITION=(550 274 2 546 278 6 558 282 10 554 286 14) # this will have more file numbers
dir1=/techbat/data/be_t1_snapshot/20140501
find "$PRIMARY" -mindepth 1 -delete
do_copy() {
el=$1
scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@${FILERS_LOCATION[1]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/.
}
export -f do_copy
parallel -j 5 do_copy ::: "${PRIMARY_PARTITION[@]}"
問題の説明:-
上記のスクリプトで直面した問題は、および内部メソッドを${FILERS_LOCATION[0]}
認識しないということです。なぜか分からないの?${FILERS_LOCATION[1]}
$dir1
$PRIMARY
do_copy
このような内部方法で印刷しようとすると、do_copy
何も印刷されませんか?
echo ${FILERS_LOCATION[0]}
echo ${FILERS_LOCATION[1]}
ところで、上記の方法で同じ内容を出力するとうまくいくdo_copy
でしょうか?
ここで何か抜けましたか?
直す:-
以下は私が使用するコードです -
#!/bin/bash
export PRIMARY=/tech01/primary
export FILERS_LOCATION=(machineB machineC)
export MEMORY_MAPPED_LOCATION=/techbat/data/be_t1_snapshot
PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280)
export dir1=/techbat/data/be_t1_snapshot/20140501
find "$PRIMARY" -mindepth 1 -delete
do_copy() {
el=$1
scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@${FILERS_LOCATION[1]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/.
}
export -f do_copy
parallel -j 8 do_copy ::: "${PRIMARY_PARTITION[@]}"
別のアップデート:-
これは、次のスクリプトを実行した後に得られた結果です。
#!/bin/bash
export PRIMARY=/tech01/primary
export FILERS_LOCATION=(slc4b03c-407d.stratus.slc.ebay.com chd1b02c-0db8.stratus.phx.ebay.com)
export MEMORY_MAPPED_LOCATION=/techbat/data/be_t1_snapshot
PRIMARY_PARTITION=(0 548 272 4 544)
export dir1=/techbat/data/be_t1_snapshot/20140501
find "$PRIMARY" -mindepth 1 -delete
echo ${FILERS_LOCATION[0]}
echo ${FILERS_LOCATION[1]}
do_copy() {
el=$1
echo "scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 bullseye@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 bullseye@${FILERS_LOCATION[1]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/."
}
export -f do_copy
parallel -j 3 do_copy ::: "${PRIMARY_PARTITION[@]}"
私が得た結果 -
david@tvxdbx1143:/home/david$ ./scp_files5.sh
machineB
machineC
When using programs that use GNU Parallel to process data for publication please cite:
O. Tange (2011): GNU Parallel - The Command-Line Power Tool,
;login: The USENIX Magazine, February 2011:42-47.
This helps funding further development; and it won't cost you a cent.
To silence this citation notice run 'parallel --bibtex' once or use '--no-notice'.
scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_0_200003_5.data /tech01/primary/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_0_200003_5.data /tech01/primary/.
scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_548_200003_5.data /tech01/primary/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_548_200003_5.data /tech01/primary/.
scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_272_200003_5.data /tech01/primary/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_272_200003_5.data /tech01/primary/.
scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_4_200003_5.data /tech01/primary/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_4_200003_5.data /tech01/primary/.
scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_544_200003_5.data /tech01/primary/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@:/techbat/data/be_t1_snapshot/20140501/t1_weekly_1680_544_200003_5.data /tech01/primary/.
答え1
エクスポートして、次のように配列を削除してみてください。bashは配列をエクスポートできません:
export PRIMARY=/data01/primary
export FILERS_LOCATION_1=machineB
export FILERS_LOCATION_2=machineC
export MEMORY_MAPPED_LOCATION=/bexbat/data/be_t1_snapshot
export dir1=/bexbat/data/be_t1_snapshot/20140501
あるいは、単にすべての定数変数を関数に入れてください。
#!/bin/bash
PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280)
PRIMARY=/data01/primary
find "$PRIMARY" -mindepth 1 -delete
do_copy() {
el=$1
PRIMARY=/data01/primary
FILERS_LOCATION=(machineB machineC)
MEMORY_MAPPED_LOCATION=/bexbat/data/be_t1_snapshot
dir1=/bexbat/data/be_t1_snapshot/20140501
scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/. || scp -o ControlMaster=auto -o 'ControlPath=~/.ssh/control-%r@%h:%p' -o ControlPersist=900 david@${FILERS_LOCATION[1]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/.
}
export -f do_copy
parallel -j 8 do_copy ::: "${PRIMARY_PARTITION[@]}"
コピーするファイルの種類に応じて、代わりに見て、一度だけ実行することrsync -z
を検討scp
する必要がありますparallel --bibtex
(並列に提案されています)。
答え2
関数をエクスポートしましたが、関数で直接使用したい変数はエクスポートされませんでした。
parallel
各実行は新しいシェルを起動しdo_copy
、そのシェル内の変数は解釈されて存在しません。
使用すると、-s SERVER
このオプションは--env VAR
初期シェルからコマンドが実行されるリモート環境にコピーされます。VAR
parallel
parallel -j 5 -S localhost --env do_copy --env PRIMARY --env FILERS_LOCATION do_copy ::: "${PRIMARY_PARTITION[@]}"
マルチサーバーロジックをパラレルサーバーオプションに実装する簡単な方法は見えないので、上記のローカルホストハッキングを避けることができます-S
(1つのサーバーにファイルがないことを保証しない限り)。
より良いアプローチは、Oleが提案したように変数をエクスポートするか、必要なすべての値を関数do_copy
に引数として渡すことです。