각 파일에 대해 하드 링크를 사용하여 디렉토리를 재귀 적으로 복사하는 방법 각 파일이

각 파일이 원본 파일에 대한 하드 링크 인 디렉토리 트리의 “복사본”을 만들고 싶습니다.

예 : 디렉토리 구조가 있습니다.

dirA/
dirA/file1
dirA/x/
dirA/x/file2
dirA/y/
dirA/y/file3

각 파일이 원본 파일에 대한 하드 링크 인 디렉토리 트리의 “복사본”인 예상 결과는 다음과 같습니다.

dirB/            #  normal directory
dirB/file1       #  hardlink to dirA/file1
dirB/x/          #  normal directory
dirB/x/file2     #  hardlink to dirA/x/file2
dirB/y/          #  normal directory
dirB/y/file3     #  hardlink to dirA/y/file3



답변

Linux (보다 정확하게 GNU와 Linux를 커널로 사용하는 시스템에서 일반적으로 busybox구현 된 구현 cp) 및 최근 FreeBSD에서 다음과 같은 방법을 사용합니다.

cp -al dirA dirB

보다 편리한 솔루션은 Stéphane Chazelas의 pax 및 cpio를 사용한 답변을 참조하십시오.


답변

POSIX pax는 다음 -l옵션을 사용 하여 읽기 + 쓰기 모드에서 사용합니다 .

pax -rwlpe -s /A/B/ dirA .

( -peGNU처럼, 복사됩니다이 경우 파일의 모든 가능한 특성 (전용 디렉토리) 보존 cp의는 -a않습니다).

이제는 표준 이지만 그 명령이 반드시 이식성 이 좋은 것은 아닙니다 .

첫째, 많은 GNU / Linux 기반 시스템은 pax기본적으로 포함 되어 있지 않습니다 (비 선택적 POSIX 유틸리티 임에도 불구하고).

그런 다음 몇 가지 구현으로 여러 버그와 부적합으로 인해 해당 코드에 많은 문제가 발생합니다.

  • 버그로 인해 Solaris 10 pax(최소한) -rwl은와 함께 사용할 때 작동하지 않습니다 -s. 어떤 이유로 든 원래 경로와 복사 된 경로 모두에 대체를 적용하는 것 같습니다. 따라서 위의 link("dirB/file", "dirB/file")대신에 일부 를 시도합니다 link("dirA/file", "dirB/file").
  • FreeBSD에서는 symlinkpax 형식의 파일에 대한 하드 링크를 만들지 않습니다 (POSIX에서 허용되는 동작). 뿐만 아니라 심볼릭 링크의 대상 ( POSIX 에서는 허용 되지 않는 동작)에 대체를 적용합니다 . 예를 들어에 심볼릭 링크가 있으면에 링크 가 됩니다 .foo -> AAdirAfoo -> BAdirB

또한 내용이 $srcand에 저장된 임의의 파일 경로를 사용하여 동일하게 수행하려는 경우 내부 의 전체 디렉토리 구조 (존재하고 디렉토리 여야 함) $dstpax -rwl -- "$src" "$dst"작성하는 것이 중요합니다 . 예를 들어, 만약 이며 , 다음, 생성됩니다.$src$dst$srcfoo/bar$dst/foo/bar

대신 $dst의 사본이 $src되고 싶다면 가장 쉬운 방법은 다음과 같습니다.

absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && pax -rwlpe . "$absolute_dst")

(위에서 언급 한 대부분의 문제를 해결할 수도 있지만 $dst줄 바꿈 문자 로 끝나는 절대 경로이면 실패합니다 ).

이제는 GNU / Linux 시스템에서 도움이되지 않습니다 pax.

paxPOSIX가 tarand cpio명령 의 기능을 병합하기 위해 만든 것을 주목하는 것이 흥미 롭습니다 .

cpioA는 과거 POSIX의 발명에 반대 (1977) 유닉스 명령 및 아니라 GNU 구현 (하지가 pax하나). 따라서 더 이상 표준 명령이 아니더라도 (SUSv2에 있음) 여전히 일반적이며 일반적으로 사용할 수있는 핵심 기능이 있습니다.

에 해당 pax -rwl합니다 cpio -pl. 하나:

  1. cpio 인수와 달리 stdin에서 입력 파일 목록을 가져옵니다 (줄 바꿈으로 구분됨). 줄 바꿈 문자가있는 파일 이름은 지원되지 않습니다.
  2. 모든 파일 (일반적으로 당신은 그것을의 출력을 공급 지정할 수 있습니다 find( findcpio) 같은 사람들에 의해 공동으로 개발되었다).
  3. 메타 데이터는 유지되지 않습니다 (일부 cpio구현에는 일부를 유지하는 옵션이 있지만 이식성이없는 것은 없습니다).

그래서 cpio:

absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && find . | cpio -pl "$absolute_dst")


답변

짧은 답변:

cd $source_folder
pax -rwlpe . $dest_folder


답변

하드 링크로 복사 (Copy-with-Hardlinks) 기능을 찾고 있다면 파일의 전체 또는 일부에 대한 스냅 샷 또는 백업을 살펴보십시오 rsnapshot.


답변

@ gudmundur-orn의 대답은 정확하지만 Linux에서 BtrFS를 사용 cp a --reflink=auto dirA dirB하는 경우 트릭을 수행해야합니다. 차이로 인해 파일이 실제로 다르고 하나를 변경해도 다른 것이 변경되지 않습니다. cp -cAPFS를 사용하는 Mac에서 거의 동일하게 달성 할 수 있습니다 ( auto가능한 경우 전체 사본 -c을 작성하고 실패 함).

모든 COW 파일 시스템이이를 수행 할 수 있어야하지만 공급 업체는 표준 명령 줄 옵션에 동의하지 않았습니다.


답변