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


38

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

그런 다음 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데 사용할 수 있습니다 . 디렉토리 a 와 b 를 인수로 전달하십시오.

#!/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.