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
(한 서버에 파일이 없다고 보장하지 않는 한?).
더 나은 접근 방식은 Ole이 제안한 대로 변수를 내보내거나 필요한 모든 값을 do_copy
함수 에 인수로 전달하는 것입니다.