끊어진 링크에서 출력하지 않고 diff -r과 두 디렉토리를 재귀 적으로 비교


38

내가 사용하고 diff -r a b반복적으로 비교 디렉토리에 와 B . 종종 깨진 링크 ( ab 디렉토리 모두에서 동일한 깨진 링크가 존재하고 존재하지 않는 동일한 대상을 가리키는) 가 있지만 종종 발생합니다 .

그런 다음 diff 는 이러한 경우 오류 메시지를 출력하고 0이 아닌 종료 코드로 종료하지만 침묵을 유지하고 디렉토리가 내 책에서 동일하므로 0으로 종료하십시오.

어떻게해야합니까?


여전히 심볼릭 링크를 비교하고 (동등하지만 고장난 것으로 식별)이 diff를 수행 할 때 모든 심볼릭 링크를 무시해도됩니까?
ire_and_curses

동등한 것으로 비교 및 ​​식별, 나는 그들이 깨진 경우 상관하지 않습니다. 내 rsync가 작동했는지 확인하려고합니다.
Marcus Junius Brutus

답변:


24

의 버전 3.3 이상 에서는 Pete Harlan의 답변에 설명 된대로 옵션을 diff사용해야합니다 .--no-dereference

불행히도, 이전 버전은 diff 심볼릭 링크 무시를 지원하지 않습니다 .

일부 파일은 디렉토리 나 일반 파일이 아닙니다. 심볼릭 링크, 장치 특수 파일, 명명 된 파이프 및 소켓과 같은 특이한 파일입니다. 현재 diff기호 링크를 일반 파일처럼 취급합니다. 다른 특수 파일은 최상위 레벨에서 지정된 경우 일반 파일처럼 취급하지만 디렉토리를 비교할 때 해당 파일의 존재를보고합니다. 이는 해당 patch파일에 대한 변경 사항을 나타낼 수 없음을 의미 합니다. 예를 들어, 심볼릭 링크가 가리키는 파일을 변경하면 심볼릭 링크를 변경하는 diff대신 두 파일의 차이를 출력합니다.

diff선택적으로 변경 사항을 특수 파일에 특별하게보고 patch해야하며 이러한 확장자를 이해하도록 확장되어야합니다.

당신이 원하는 모든 rsync를 확인하는 것 (그리고 아마도 누락 된 것을 수정하는 것)이라면 rsync 명령을 두 번 실행할 수 있습니다. 그렇게하고 싶지 않다면 , 디렉토리를 체크섬하는 것으로 충분할 수 있습니다.

이 작업을 실제로 수행 하려면 심볼릭 링크를 건너 뛰고 각 파일에서 개별적으로 diff를 실행 diff하는 find데 사용할 수 있습니다 . 디렉토리 ab 를 인수로 전달하십시오.

#!/bin/bash
# Skip files in $1 which are symlinks
for f in `find $1/* ! -type l`
do
    # Suppress details of differences
    diff -rq $f $2/${f##*/}
done

또는 단일 라이너로 :

for f in `find a/* ! -type l`;do diff -rq $f b/${f##*/};done

컨텐츠가 다른 파일 또는 a에 있지만 b에 없는 파일을 식별합니다 .

참고 :

  • 심볼릭 링크를 완전히 건너 뛰기 때문에 심볼릭 링크 이름이 b에 없으면 알 수 없습니다 . 필요한 경우 모든 심볼릭 링크를 식별 한 다음 b 에 해당 심볼이 존재하는지 명시 적으로 확인하려면 두 번째 찾기 단계가 필요합니다 .
  • 목록은 a 의 내용으로 구성되므로 b의 추가 파일은 식별되지 않습니다 . 아마도 시나리오 에는 문제가되지 않습니다 .rsync

제안 된 스크립트는 'a'디렉토리에있는 디렉토리에 대해 재귀 적으로 작동하지 않습니다 (b / $ {f ## *}를 사용하여 'b'에 대해 작성된 경로가 올바르지 않습니다).
Marcus Junius Brutus

@MarcusJuniusBrutus-그렇습니다. 해결책은 #을 제거하는 것입니다 for f in . 유형 l ;do echo $f b/${f#*/};done. 나는 지금 이것을 테스트 할 시간이 없다. 그것이 작동하는지 알려주세요.
ire_and_curses

그것은 이다 아직도 많은 경우에 filepaths를 망쳐 놨 더 나은 그러나. #을 제거한 스크립트는 'a'를 통해 직접 디렉토리에서 호출해야합니다.
Marcus Junius Brutus

이 답변은 GNU diff 3.3을 사용할 때 더 이상 사용되지 않습니다 (아래 게시물 참조)
Bernd Gloss

위의 스크립트는 먼저 모든 파일 이름을 찾아 확장 된 명령 줄에 공급하기 때문에 몇 가지 문제가 있습니다. (1) 작은 파일 모음에서만 작동합니다. (2) 특수 문자 (공백 포함)가있는 파일 이름은 처리되지 않습니다. (3) 항상 $(xxx)백틱 대신 사용하십시오 . 백틱 대칭은 읽기가 어렵고 중첩을 방지합니다. 1과 2에 대해서는 stackoverflow.com/questions/11366184/…를
Stéphane Gourichon

19

버전 3.3부터 GNU diff는 심볼릭 링크 역 참조를 지원하지 않지만 그들이 가리키는 경로를 비교합니다.

GNU diffutils> = 3.3을 설치 하고 --no-dereference옵션을 사용하십시오 . 이에 대한 짧은 옵션은 없습니다.

다음과 같은 경우 진단이 자동으로 수행됩니다.

심볼릭 링크 /tmp/noderef/a/symlink/tmp/noderef/b/symlink다른


이제 심볼릭 링크가 일반 파일 인 것처럼 내용 변경 사항 만 표시한다면 ... :-/
lindes

6

최신 버전을 사용할 수 있습니다 diff

diffGNU에서 diffutils3.3이 포함되어 --no-dereference당신이 그들의 목표보다는 심볼릭 링크 자신을 비교할 수 있습니다 옵션을 선택합니다. 차이가있을 경우보고하고 동의하면 조용하며 고장 여부를 신경 쓰지 않습니다.

옵션이 언제 추가되었는지 모르겠습니다. 2.8.1에는 없습니다.


나는 diff (GNU diffutils) 3.2에도 존재하지 않는다는 것을 확인할 수있다
Geek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.