"변경된 경우 복사"작업을 수행하려면 어떻게해야합니까?


34

디렉토리 A의 파일이 디렉토리 B의 파일과 동일하면 해당 파일을 복사해서는 안된다는 점에주의를 기울여 디렉토리 A에서 디렉토리 B로 파일 세트를 복사하고 싶습니다. 업데이트). 내 자신의 스크립트를 작성하지 않고 기존 도구로 그렇게 할 수있는 방법이 있습니까?

유스 케이스를 조금 더 정교하게하기 위해 : 나는 .c임시 디렉토리에 많은 파일을 자동 생성하고 있다 (무조건 모든 파일을 무조건 생성 해야하는 방법으로). 그리고 파일을 다시 생성 할 때만 복사하고 싶다. 실제 소스 디렉토리로 변경되어 변경되지 않은 디렉토리는 수정하지 않고 (이전 생성 시간과 함께) make다시 컴파일 할 필요가 없음을 알 수 있습니다. (생성 된 모든 파일이 .c파일 인 것은 아니므로 텍스트 비교보다는 이진 비교를 수행해야합니다.)

(참고로이 내가 있슴 질문 밖으로 성장 https://stackoverflow.com/questions/8981552/speeding-up-file-comparions-with-cmp-on-cygwin/8981762#8981762 내가하려고했던 곳, 이 작업을 수행하는 데 사용했던 스크립트 파일의 속도를 높이기 위해, 나 자신에게 직접 스크립트를 작성하는 것보다 더 좋은 방법이 있는지 묻습니다. 특히 쉘 에서이 작업을 수행하는 간단한 방법 때문에 스크립트는 cmp모든 파일 쌍에서 와 같은 것을 호출 하며 모든 프로세스를 시작하는 데 너무 오래 걸립니다.)


1
, 및 diff -qr dirA dirB고유 한 파일을 확인하는 데 사용할 수 있습니다 . dirAdirB

1
@ brooks-moses 이것은 실제로 ccache에 적합한 직업입니다 !
aculich

3
@hesse 당신이 독특한 파일을 보여주고 싶다면 diff를 사용할 수 있지만 변경된 것을보고 싶다면 rsync -avnc먼 길 을 사용 하십시오 rsync --archive --verbose --dry-run --checksum.
aculich

답변:


29

rsync가 아마도 가장 좋은 도구 일 것입니다. 이 명령에는 많은 옵션이 있으므로 man page를 읽으십시오 . --checksum 옵션이나 --ignore-times를 원한다고 생각합니다


나는 이미 그것을 시도했지만 성공하지 못했습니다. 두 옵션 모두 rsync가 복사를 수행 하는지 여부 에만 영향을 미칩니다. 그러나 복사를 수행하지 않더라도 대상 파일의 수정 시간을 소스와 동일하게 ( -t옵션이 지정된 경우) 또는 동기화 시간으로 업데이트합니다. ( -t지정하지 않은 경우).
Brooks Moses

4
@ 브룩스 모세 : 그렇지 않습니다. 적어도 내 버전은 rsync그렇지 않습니다. 내가 이렇게하면 : mkdir src dest; echo a>src/a; rsync -c src/* dest; sleep 5; touch src/a; rsync -c src/* dest, stat dest/amtime과 ctime이의 것보다 5 초 더 오래되었음을 보여줍니다 src/a.
angus

@angus : 허. 그래, 네 말이 맞아 핵심은 --checksum옵션 인 것으로 보이며 linux.die.net/man/1/rsync 에는 수정 날짜가 업데이트되는지 여부에 영향을 줄 수있는 아무것도 포함되어 있지 않지만 대상 수정 날짜가 남습니다. 손대지 않은. (반면, --ignore-times옵션은이 효과를 갖지 않습니다. 수정 날짜는 여전히 업데이트됩니다.) 이것이 완전히 문서화되지 않은 것으로 보았을 때, 나는 그것에 의존 할 수 있습니까?
Brooks Moses

2
@ BrooksMoses : 당신이 그것에 의존 할 수 있다고 생각합니다 : rsync의 워크 플로우는 다음과 같습니다 : 1) 파일을 업데이트 해야하는지 확인하십시오. 2) 그렇다면 파일을 업데이트하십시오. --checksum옵션은 그래서,이 업데이트되지해야한다고 rsync) 2 단계로 진행하지 않는 것이 좋습니다.
enzotib 2012 년

2
@BrooksMoses : --ignore-times없이는 --checksum모든 파일을 복사하므로 파일이 동일한 경우에도 타임 스탬프를 업데이트합니다.
enzotib 2012 년

13

-u스위치를 사용하여 다음 cp과 같이 할 수 있습니다 .

$ cp -u [source] [destination]

매뉴얼 페이지에서 :

   -u, --update
       copy only when the SOURCE file is newer than the destination file or 
       when the destination file is missing

4
안녕하세요. 사이트에 오신 것을 환영합니다. 우리는 여기에서 답변이 좀 더 실질적 일 것으로 기대합니다. 예를 들어, -u플래그의 기능과 작동 방식 및 이것이 OP에 어떻게 도움이되는지에 대한 설명을 포함시킬 수 있습니다 . 그러나이 특정 경우에는 최신 파일 인 경우 동일한 파일을 복사하므로 OP가 피하고자하는 타임 스탬프를 변경하므로 OP에 도움이되지 않습니다.
terdon

1
이미 삭제 된 유사한 A에 대한 의견에서 : "소스의 타임 스탬프가 더 최신 인 경우 동일한 파일을 복사하므로 OP 요청에 대해 대상의 타임 스탬프를 업데이트하므로 작동하지 않습니다."
slm

전혀 질문에 대답하지 않지만 여전히 유용하다는 것을 알았습니다.
user31389

7

사용 rsync --checksum하는 것이 "변경된 경우 복사"하는 좋은 일반적인 방법 이지만 특정 경우에는 더 나은 해결책이 있습니다!

불필요하게 파일을 다시 컴파일하지 않으려면 정확하게이 목적으로 빌드 된 ccache 를 사용해야합니다 ! 실제로, 자동 생성 된 파일의 불필요한 재 컴파일을 피할뿐만 아니라 make clean처음부터 다시 컴파일 할 때마다 속도가 향상됩니다 .

다음으로 "안전합니까?"라고 물을 것입니다. 네, 웹 사이트가 지적한대로 :

안전 해요?

예. 컴파일러 캐시의 가장 중요한 측면은 항상 실제 컴파일러와 동일한 결과를 생성하는 것입니다. 여기에는 실제 컴파일러를 사용할 경우 생성되는 것과 동일한 객체 파일과 정확히 동일한 컴파일러 경고가 포함됩니다. ccache를 사용하고 있다고 말할 수있는 유일한 방법은 속도입니다.

그리고 makefile 줄에 접두사로 추가하면 쉽게 사용할CC= 수 있습니다 (또는 심볼릭 링크를 사용할 수는 있지만 makefile 방식이 더 좋습니다).


1
나는 처음에 오해하고 ccache를 사용하여 생성의 일부를 수행한다고 제안한다고 생각했지만 이제는 이해합니다. 제 모든 파일을 복사 한 다음 빌드 프로세스에서 ccache를 사용하여 파일을 다시 작성하지 않도록 제안했습니다. 변경되지 않았습니다. 좋은 생각이지만 제 경우에는 좋지 않습니다. 수백 개의 파일이 있으며 일반적으로 한 번에 하나 또는 두 개만 변경하고 Cygwin에서 실행 중입니다. 파일은 몇 분이 걸릴 것입니다. 그럼에도 불구하고 대부분의 사람들에게 좋은 답변이기 때문에 공감했습니다!
Brooks Moses

아니요, 모든 파일을 복사 할 것을 제안하지는 않았습니다. 대신 .c 파일을 자동으로 생성 할 수 있습니다 (복사 단계를 제거하고 직접 작성). 그런 다음 ccache를 사용하십시오. 수백 개의 ccache 프로세스를 시작하여 의미하는 바를 모르겠습니다 .gcc를 둘러싼 경량 래퍼 일 뿐이며 프로젝트의 다른 부분도 빠르게 재구성 할 수 있습니다. 사용해 보셨습니까? copy-method와 ccache를 사용하는 타이밍을 비교하고 싶습니다. 실제로 두 가지 방법을 결합하여 두 가지 이점을 얻을 수 있습니다.
aculich

1
알았어, 이제 복사에 대해 이해 했어 명확하게 말하면, 이것이 의미하는 바는 다음과 같습니다. 파일을 제 위치에 생성하면 ccache file.c -o file.o수백 개의 file.c파일 이 있기 때문에 수백 번 호출해야 합니다. 내가 cmp아닌 으로 작업을 수행 할 때 ccache몇 분이 걸렸 으며 , cmp가볍습니다 ccache. 문제는 Cygwin에서 프로세스를 시작하는 데 완전히 사소한 프로세스조차도 무시할 수없는 시간이 걸린다는 것입니다.
Brooks Moses

1
데이터 포인트로 for f in src/*; do /bin/true.exe; done30 초가 걸립니다. 어쨌든 Windows 기반 편집기를 선호하며 이러한 종류의 타이밍 문제를 제외하고 Cygwin은 빌드 서버에 업로드하지 않으면 로컬에서 물건을 테스트하기위한 가벼운 장소로 워크 플로우와 잘 작동합니다. 쉘과 편집기를 동일한 OS에 두는 것이 유용합니다. :)
Brooks Moses

1
Windows 기반 편집기를 사용 하려면 Guest Additions를 설치하면 공유 폴더 를 사용하여 쉽게 수행 할 수 있지만 Cygwin이 적합하다면 누구를 말해야합니까? 이런 이상한 농구를 뛰어 넘어야한다는 것은 부끄러운 일입니다 ... 일반적으로 VM에서도 컴파일이 더 빠릅니다.
aculich 2012

3

이것은 필요한 것을해야합니다.

diff -qr ./x ./y | awk '{print $2}' | xargs -n1 -J% cp % ./y/

어디에:

  • x는 업데이트 / 새 폴더입니다
  • y는 복사 할 대상입니다
  • awk는 diff 명령에서 각 줄의 두 번째 인수를 취합니다 (공간이있는 파일 이름에는 추가 항목이 필요할 수 있습니다-지금 시도 할 수 없습니다)
  • xargs -J %는 파일 이름을 적절한 위치에 cp에 삽입합니다

1
-1 이것은 지나치게 복잡하고 이식 가능하지 않기 때문에 ( -Jbsd에 따라 다릅니다; GNU xargs에서는 -I), 같은 파일 세트가 두 위치에 모두 존재하지 않으면 올바르게 작동하지 않습니다 ( touch x/boo그런 다음 grep이 나에게주는 경우) Only in ./x: boo파이프 라인에 오류가 발생합니다). 작업용으로 제작 된 도구를 사용하십시오 (예 :) rsync --checksum.
aculich

또는이 특정 경우에는 ccache를 사용하는 것이 좋습니다 .
aculich

잘 알려진 명령의 집합 내가 (여기 DIFF을 수행하기위한 온) 유사한 작업에 사용 깰 수 있기 때문에 하나는, 여전히 rsync를 더 나은이 특정 작업에 대한있을 수 있습니다
NTG

3

내가 사용하고자 한마음 찬성 rsync, 그것은 여러 마스터를 지원하기 때문에 VPN을 별도로 이미 설치 내 SSH 키을 갖는.

따라서 하나의 호스트로 구성된 crontab에서는 15 분마다 동기화되도록했습니다.

* / 15 * * * * [-z "$ (pidof unison)" "& & (시간 종료 25m unison -sortbysize -ui text -batch -times / home / master ssh : //192.168.1.12//home/master -path dev -logfile /tmp/sync.master.dev.log) &> /tmp/sync.master.dev.log

그런 다음 양쪽에서 개발할 수 있으며 변경 사항이 전파됩니다. 실제로 중요한 프로젝트의 경우 동일한 트리를 미러링하는 서버를 최대 4 대까지 보유하고 있습니다 (3 대는 cron에서 동시에 실행되고 그렇지 않은 서버를 가리킴). 실제로 Linux와 Cygwin 호스트는 혼합되어 있습니다. 단, cygwin 환경 외부의 win32에있는 소프트 링크에서는 의미가 없습니다.

이 경로를 이동하는 경우가없는 빈 쪽의 초기 거울을 -batch, 즉,

unison -ui text  -times /home/master ssh://192.168.1.12//home/master -path dev

물론 백업 파일, 아카이브 등을 무시하는 구성이 있습니다.

 ~/.unison/default.prf :
# Unison preferences file
ignore = Name {,.}*{.sh~}
ignore = Name {,.}*{.rb~}
ignore = Name {,.}*{.bak}
ignore = Name {,.}*{.tmp}
ignore = Name {,.}*{.txt~}
ignore = Name {,.}*{.pl~}
ignore = Name {.unison.}*
ignore = Name {,.}*{.zip}

    # Use this command for displaying diffs
    diff = diff -y -W 79 --suppress-common-lines

    ignore = Name *~
    ignore = Name .*~
    ignore = Path */pilot/backup/Archive_*
    ignore = Name *.o

나는 그것을 보았지만 unison"파일 마지막 수정 날짜를 업데이트하지 마십시오"라는 의미 의 옵션을 찾을 수 없었습니다 . 하나 있습니까? 그렇지 않으면 이것은 완전히 다른 문제에 대한 훌륭한 해답입니다.
Brooks Moses

1
-times나를 위해 그렇게합니다. Unison도 드라 이런 모드를 가지고 있다고 생각합니다.
Marcos

글쎄, 설정 times=false(또는 떠나기 -times)은 그렇게 할 것입니다. 이전 문서에서 어떻게 놓쳤는 지 모르겠습니다. 감사!
Brooks Moses

기쁘다. 나는 modtimes, 권한 및 소프트 링크와 같은 것들을 보존 할 때 stickler입니다. 종종 간과
마르코스

1

하지만 rsync --checksum정답이 옵션과 호환되지 않습니다이다 --times, 그것은 --archive포함 --times당신이 할 그렇다면 rsync -a --checksum, 당신이 정말로 필요 rsync -a --no-times --checksum.


'호환되지 않는다'는 말의 의미는 무엇입니까?
오븐

"정답"이란 무엇을 의미합니까?
thoni56
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.