Gnu 병렬을 사용한 후 변수 값을 인식할 수 없습니까?

Gnu 병렬을 사용한 후 변수 값을 인식할 수 없습니까?

5개의 파일을 병렬로 복사하려고 하는 다음 쉘 스크립트가 있습니다. 나는 machineAmachineB와 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$PRIMARYdo_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초기 셸에서 명령이 실행되는 원격 환경으로 복사됩니다.VARparallel

parallel -j 5 -S localhost --env do_copy --env PRIMARY --env FILERS_LOCATION do_copy ::: "${PRIMARY_PARTITION[@]}"

다중 서버 논리를 병렬 서버 옵션에 구현하는 쉬운 방법이 보이지 않으므로 위의 로컬 호스트 해킹을 피할 수 있습니다 -S(한 서버에 파일이 없다고 보장하지 않는 한?).

더 나은 접근 방식은 Ole이 제안한 대로 변수를 내보내거나 필요한 모든 값을 do_copy함수 에 인수로 전달하는 것입니다.

관련 정보