지정된 이름의 디렉터리를 반복적으로 복사합니다.

지정된 이름의 디렉터리를 반복적으로 복사합니다.

빌드된 디렉터리 구조 사용

#!/bin/bash
for name in A B
do
    mkdir -p /tmp/src/${name}/copyme
    echo "do not copy" > /tmp/src/${name}/no.txt
    echo "copy" > /tmp/src/${name}/copyme/yes.txt
done

copyme나는 단지 디렉토리와 그 안의 파일을 /tmp/tgt로 미러링 하고 싶습니다 .

이는 간단해야 합니다. rsync명령줄 옵션의 순서를 구별하여 모든 것을 제외하고 관련 패턴을 포함합니다 . 하지만

rsync -av --exclude='*' --include='copyme' /tmp/src/ /tmp/tgt/

모든 항목을 제외합니다(대상 디렉터리만 생성). 왜?

답변1

실행하면 rsync소스에서 찾은 이름을 패턴과 비교하여 테스트하고 첫 번째로 일치하는 패턴이 적용됩니다.

$ rsync -avv --exclude='*' --include='copyme' /tmp/src/ /tmp/tgt/
sending incremental file list
[sender] hiding directory A because of pattern *
[sender] hiding directory B because of pattern *
delta-transmission disabled for local transfer or --whole-file
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 51 bytes  received 86 bytes  274.00 bytes/sec
total size is 0  speedup is 0.00

디렉토리가 제외되면(위의 "숨겨진 디렉토리..." 참조) 해당 내용은 더 이상 고려되지 않습니다. 제외 및 포함 패턴을 반대로 하면 copyme디렉터리에 도달하지 않으므로 도움이 되지 않습니다.

설명서에는 다음과 rsync같이 나와 있습니다.

/foo/bar/baz예를 들어 , 디렉터리를 포함하려면 /foo/foo/bar제외하면 안 됩니다. 이러한 상위 디렉터리 중 하나를 제외하면 해당 내용을 검사할 수 없으며, rsync이러한 경로의 재귀를 차단 하고 포함을 무효화합니다 /foo/bar/baz( rsync디렉터리 계층 구조의 컷오프 부분에 전혀 표시되지 않는 콘텐츠를 일치시키는 것이 불가능하기 때문입니다).

그래서 대신:

$ rsync -avv --include='[AB]' --include='copyme/***' --exclude='*' /tmp/src/ /tmp/tgt/
sending incremental file list
[sender] showing directory A because of pattern [AB]
[sender] showing directory B because of pattern [AB]
[sender] showing directory A/copyme because of pattern copyme/***
[sender] hiding file A/no.txt because of pattern *
[sender] showing file A/copyme/yes.txt because of pattern copyme/***
[sender] showing directory B/copyme because of pattern copyme/***
[sender] hiding file B/no.txt because of pattern *
[sender] showing file B/copyme/yes.txt because of pattern copyme/***
created directory /tmp/tgt
delta-transmission disabled for local transfer or --whole-file
./
A/
A/copyme/
A/copyme/yes.txt
B/
B/copyme/
B/copyme/yes.txt
total: matches=0  hash_hits=0  false_alarms=0 data=10

sent 305 bytes  received 175 bytes  960.00 bytes/sec
total size is 10  speedup is 0.02

제외는 포함 뒤에 와야 합니다. 이 copyme/***패턴은 copyme디렉터리 이름 자체 및 그 아래의 모든 경로 이름과 일치합니다.

A및 디렉터리 이름 B을 하드코딩 하지 않으려면 다음을 수행하세요 .

for dir in /tmp/src/*; do
    [ ! -d "$dir" ] && continue
    rsync -avv --include="${dir##*/}" --include='copyme/***' --exclude='*' /tmp/src/ /tmp/tgt/
done

이것은 출력됩니다

sending incremental file list
[sender] showing directory A because of pattern A
[sender] hiding directory B because of pattern *
[sender] showing directory A/copyme because of pattern copyme/***
[sender] hiding file A/no.txt because of pattern *
[sender] showing file A/copyme/yes.txt because of pattern copyme/***
created directory /tmp/tgt
delta-transmission disabled for local transfer or --whole-file
./
A/
A/copyme/
A/copyme/yes.txt
total: matches=0  hash_hits=0  false_alarms=0 data=5

sent 180 bytes  received 148 bytes  656.00 bytes/sec
total size is 5  speedup is 0.02
sending incremental file list
[sender] hiding directory A because of pattern *
[sender] showing directory B because of pattern B
[sender] showing directory B/copyme because of pattern copyme/***
[sender] hiding file B/no.txt because of pattern *
[sender] showing file B/copyme/yes.txt because of pattern copyme/***
delta-transmission disabled for local transfer or --whole-file
B/
B/copyme/
B/copyme/yes.txt
total: matches=0  hash_hits=0  false_alarms=0 data=5

sent 180 bytes  received 117 bytes  594.00 bytes/sec
total size is 5  speedup is 0.02

결과는 다음과 같습니다

$ tree src tgt
src
|-- A
|   |-- copyme
|   |   `-- yes.txt
|   `-- no.txt
`-- B
    |-- copyme
    |   `-- yes.txt
    `-- no.txt

4 directories, 4 files
tgt
|-- A
|   `-- copyme
|       `-- yes.txt
`-- B
    `-- copyme
        `-- yes.txt

4 directories, 2 files

또 다른 접근 방식은 제외 또는 포함 패턴을 사용하지 않고 rsync디렉터리 를 find찾아 복사하는 것입니다.copymersync

find /tmp/src -type d -name 'copyme' -prune -exec sh -c '
    cd /tmp/src && rsync -aRvv "${1#/tmp/src/}/" /tmp/tgt/' sh {} ';'

-R여기에 사용된 ( --relative) 플래그를 참고하십시오 rsync.

sh -c발견된 각 디렉토리에 대해 copyme실행되는 스크립트는 to cd작업을 수행 /tmp/src한 다음 경로 이름을 복사하고 /tmp/src해당 경로의 초기 비트를 제거합니다.

-prune중지 명령은 find이미 발견된 디렉토리 내에서 find추가 디렉토리를 검색합니다 .copyme

관련 정보