Bash 쉘 스크립트에서 한 번에 하나씩 대신 세 개의 파일을 동시에 복사하려면 어떻게 해야 합니까?

Bash 쉘 스크립트에서 한 번에 하나씩 대신 세 개의 파일을 동시에 복사하려면 어떻게 해야 합니까?

machineA.NET에서 파일을 변환 하는 쉘 스크립트를 실행 중입니다 machineB.machineCmachineA

파일이 에 없으면 반드시 machineB에 있어야 합니다. machineC그래서 먼저 파일을 복사해 보고 machineB, 파일이 없으면 동일한 파일을 복사 machineB해 보겠습니다 .machineC

이 폴더 안에는 다음과 같은 폴더가 machineB있습니다 .machineCYYYYMMDD

/data/pe_t1_snapshot

따라서 위 폴더 내에서 이 형식의 최신 날짜가 무엇이든 간에 YYYYMMDD해당 폴더를 파일 복사를 시작해야 하는 전체 경로로 선택하겠습니다.

20140317따라서 이것이 내부의 최신 날짜 폴더라면 /data/pe_t1_snapshot이것이 내 전체 경로가 될 것이라고 가정해 보겠습니다.

/data/pe_t1_snapshot/20140317

machineB어디 에서 파일 복사를 시작해야 할까요 machineC? 및 400에서 파일을 복사해야 합니다. 각 파일 크기는 입니다.machineAmachineBmachineC2.5 GB

이전에는 파일을 하나씩 복사하려고 했는데 machineA속도가 매우 느렸습니다. machineABash 쉘 스크립트의 스레드를 사용하여 "3개" 파일을 한 번에 복사 할 수 있는 방법이 있습니까 ?

machineA다음은 from machineB및 으로 파일을 하나씩 복사하는 쉘 스크립트입니다 machineC.

#!/usr/bin/env bash

readonly PRIMARY=/export/home/david/dist/primary
readonly FILERS_LOCATION=(machineB machineC)
readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot

PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280 12 552 284 16 256 564 20 260 560 24 264 572) # this will have more file numbers around 200

dir1=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[0]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
dir2=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[1]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)

## Build your list of filenames before the loop. 
for n in "${PRIMARY_PARTITION[@]}"
do
    primary_files="$primary_files :$dir1"/t1_weekly_1680_"$n"_200003_5.data
done

if [ "$dir1" = "$dir2" ]
then
    find "$PRIMARY" -mindepth 1 -delete
    rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ 2>/dev/null
    rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ 2>/dev/null
fi  

그래서 한 번에 하나의 파일을 복사하는 대신 "세"개의 파일을 한 번에 복사하는 것이 어떨까요? 세 개의 파일이 완료되면 목록에 있는 다른 세 개의 파일로 이동하여 복사하겠습니다. 같은 시간?

세 개의 퍼티 인스턴스를 열고 동시에 세 인스턴스 모두에서 파일을 복사해 보았습니다. 세 파일 모두 약 50초 만에 복사되었으므로 제게는 빠른 속도입니다. 이런 이유로 한 번에 하나의 파일을 복사하는 대신 한 번에 세 개의 파일을 복사해 보았습니다.

괜찮나요? 그렇다면 누구든지 예를 들어 줄 수 있습니까? 나는 단지 그것을 시험해보고 그것이 어떻게 진행되는지 보고 싶었습니다.

@terdon은 위의 문제를 해결하는 데 도움이 되었지만 한 번에 세 개의 파일을 복사하여 어떻게 작동하는지 확인하고 싶습니다.

고쳐 쓰다:-

다음은 위의 쉘 스크립트를 단순화한 버전입니다. machineB그렇게 하면 machineC에 존재하는 파일 번호를 복사하려고 시도합니다.machineAmachineAPRIMARY_PARTITION

#!/usr/bin/env bash

readonly PRIMARY=/export/home/david/dist/primary
readonly FILERS_LOCATION=(machineB machineC)
readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot

PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280 12 552 284 16 256 564 20 260 560 24 264 572) # this will have more file numbers around 200

dir1=/data/pe_t1_snapshot/20140414
dir2=/data/pe_t1_snapshot/20140414

## Build your list of filenames before the loop. 
for n in "${PRIMARY_PARTITION[@]}"
do
    primary_files="$primary_files :$dir1"/t1_weekly_1680_"$n"_200003_5.data
done

if [ "$dir1" = "$dir2" ]
then
    # delete the files first and then copy it.
    find "$PRIMARY" -mindepth 1 -delete
    rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/
    rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/
fi

답변1

여러 복사본을 병렬로 수행하는 것은 거의 유용하지 않습니다. 제한 요소가 네트워크 대역폭이든 디스크 대역폭이든 상관없이 각각 1/N배 더 빠른 N 병렬 스트림이 생성됩니다.

반면에 여러 소스(여기서는 B와 C)에서 복제할 때 병목 현상이 B와 C 측(공통 측이 아닌)에 있는 경우입니다. 따라서 병렬로 복사를 시도할 수 있습니다.

rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ &
rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ &
wait

두 개의 rsync 명령의 출력이 함께 혼합되어 별도의 파일로 보낼 수 있습니다.

log_base=$(date +%Y%m%d-%H%M%S-$$)
rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ >$log_base-B.log &
rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ >$log_base-C.log &
wait

스크립트에서 동일한 대상에 대해 여러 SSH 연결을 사용합니다. SSH 연결을 설정하는 데 피할 수 없는 지연이 있습니다. 연결을 열어두고 재사용하면 시간을 절약할 수 있습니다.주요 연결.

답변2

다음을 사용하여 여러 작업을 병렬로 수행할 수 있습니다.백스테이지 과정. 일반적인 예를 들면 다음과 같습니다.

rsync foo machine1: &
rsync bar machine2: &
rsync baz machine3: &
wait

wait프로그램이 이전 지점 이상으로 진행되지 않는지 확인하십시오.모두스크립트에 의해 생성된 백그라운드 프로세스가 완료되었습니다.

명령 구분 기호처럼 작동하기 &때문에 각 명령줄 맨 끝에 있습니다 .;

관련 정보