빌드된 디렉터리 구조 사용
#!/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
찾아 복사하는 것입니다.copyme
rsync
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