2014-07-06 2 views
1

큰 디렉토리 트리를 처리하기 위해 bash 스크립트를 작성하고 여러 스트림에서 rsync를 작성하려고합니다. 이 사이트에 대한 다른 연구에서 다음과 같이 구성했습니다. 가정은 명령이 실행된다병렬 옵션을 사용할 때 xargs에 여러 하위 명령을 전달하는 방법

program.sh/입/위치/출력/위치 $ 스레드

내 스크립트의 핵심 라인은 위의 생각이다

cd $1; find . -depth \(-type d -printf \""%p/\"\n" \) | xargs -n1 -P$3 -I% rsync -lptgoDds --delete --backup --backup-dir=$INCREMENTALS/$DATE/$1 % $2/% 

입니다 특정 지점의 모든 디렉토리를 찾은 다음 rsync 명령의 병렬 인스턴스에 전달하여 $ 1에서 $ 2로 데이터를 복사하십시오.

rsync 문제는 입력 구문 분석 방법에 따라 아직 존재하지 않는 중첩 폴더를 만들어야 할 수 있습니다. (적어도 나는 그것이 내가보고있는 오류의 원인이라고 생각한다). 이 문제를 해결하기 위해 rsync에서 두 개의 명령을 실행할 수 있다고 생각했습니다. 첫 번째 명령은 디렉토리를 만들고 두 번째 명령은 rsync를 시작합니다. 이 같은

뭔가 :

cd $1; find . -depth \(-type d -printf \""%p/\"\n" \) | xargs -n1 -P$3 -I% 'mkdir -p %;rsync -lptgoDdsv --delete % $2/%;' 

하지만 그 중 하나가 작동하지 않는 것 같습니다.

지금 이걸 갖고 놀았으니 도움을 청합니다. :-)

+0

정확히 어떤 방식으로 작동하지 않습니까? 오류가 있습니까? –

+0

'-exec' 옵션을'xargs' 대신에'find'와 함께 사용하는 것이 더 낫습니다. –

+0

예 하위 디렉터리가 상위 디렉터리보다 먼저 처리되기 때문에 "디렉터리를 찾을 수 없습니다"오류가 발생했습니다. 나는 그러나 발견에서 깊이 벗어났다. 그리고 그것은 그것을 고쳤을지도 모른다. -P 함수를 사용하여 xargs를 병렬 처리하기 때문에 -exec를 사용하고 싶지 않습니다. –

답변

0

그것은 GNU의 예 http://www.gnu.org/software/parallel/man.html#example__parallelizing_rsync 당신이 원하는 것을 꽤 가까운 병렬 보인다 GNU 병렬이를 위해 포장되지

cd $1; find . -depth -type d | parallel -P$3 mkdir -p $INCREMENTALS/$DATE/$1 $2/{}\; rsync -lptgoDds --delete --backup --backup-dir=$INCREMENTALS/$DATE/$1 {} $2/{} 

경우

cd src-dir; find . -type f -size +100000 | parallel -v ssh fooserver mkdir -p /dest-dir/{//}\;rsync -Havessh {} fooserver:/dest-dir/{} 

대신이 작동한다고 시스템에 10 초 안에 설치해야합니다.

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash 

자세히 알아보기 : W 빠른 소개를 위해 소개 비디오를보십시오 : https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

튜토리얼 (man parallel_tutorial)을 살펴보십시오. 당신은 명령 줄 그것을 사랑합니다.

1

작은 따옴표로 된 복잡한 명령을 xargs과 같이 전달할 수 없습니다. 하지만 sh으로 전달하고 xargs으로 전달할 수 있습니다.

cd $1; find . -depth \(-type d -printf \""%p/\"\n" \) | xargs -n1 -P$3 -I% sh -c 'mkdir -p %;rsync -lptgoDdsv --delete % $2/%;' 

는 (나는 이것을 테스트 할 수있는 방법이 없습니다. 그것은 여전히 ​​적응이 필요할 수 있습니다.)

0

그냥 다시 와서 내가 대답은 생각-게시물을 다시 할 수 있습니다. 필자는 쉘 호출을 사용하여 내가해야 할 일을해야만했다. 많은 시행 착오 끝에 나에게 생긴 대답은 필드를 하위 셸로 전달하는 것이 매우 간단했다. 그것들을 내 보내면 하위 셸에서 사용할 수있게되며 매력처럼 작동합니다. 여기에 현재 스크립트가 있습니다.

#!/bin/bash 
set -x 

export INCREMENTALS="/var/backup/data" 
export DATE=`date +%F` 
export SRCDIR=$1 
export TARGETDIR=$2 
export THREADS=$3 


cd $SRCDIR; find . -type d -print0 | xargs -0 -n1 -P$THREADS -I {} sh -c 'echo $TARGETDIR/"{}"; mkdir -p $TARGETDIR/"{}"; rsync -lptgoDdXvz --delete --backup --backup-dir=$INCREMENTALS/$DATE/.$SRCDIR "{}"/ $TARGETDIR/"{}"' 

당신이 순서 사용하는 스크립트를 실행하려면 :

rsync.sh /from/dir /to/dir 20 

첫 번째 두 개의 매개 변수가 명백을의 "20"은 호출 할 rsync를 스레드의 수입니다.

이 방법을 사용하면 많은 병렬 rsync를 컴퓨터를 소모하는 시점까지 밀고 있습니다. 내가 찾은 유일한 잡은 점은 수천 개의 파일이있는 디렉토리가 있으면 다른 모든 파일이 끝나고 가장 긴 파일 뒤에 대기하고 있기 때문에 병렬 처리가 떨어져 버린다는 것입니다. 저는 라운드 II에서 스프레이 접근법을 더 많이 할 수있는 방법을 찾으려고합니다.

내 유일한 다른 문제는 시간이 지남에 따라 메모리 소비가 증가한다는 것입니다. 필자의 스크립트와 관련이없는 누수가 있다는 재미있는 느낌이 들지만, 나는 계속해서 증가하는 메모리 사용을 야기하는 무한한 요소를 가지고 있을지 모른다는 걱정이 듭니다. 아직 해결해야 할 또 다른 문제는 이것과 무관합니다.

net-net 대답은 함수를 '내보내는'것이었고 하위 쉘은 내용을 올바르게 보았고 정말 잘 작동합니다.