왜 유닉스 mv 프로그램이 디렉토리에 대해 -R (재귀) 옵션이 필요하지 않지만 cp가 필요합니까? 할 때 옵션을”

사용해야 할 때 나는 항상 엉망 cp또는 mv“내가 필요합니까 -R? 디렉토리로 작업 할 때 옵션을” GNU coreutils cp에는 필요 -R하거나 필요 mv하지 않습니다.

나는 dirs를 복사하기위한 옵션이 cp필요한 이유를 찾을 수 없지만 그렇지 않습니다. 나는 생각 없이 DIRS을 보내고 (하지만이처럼 반복적으로 행동 하고 좋아 하는 일은) 도구를 사용하여 사람의 습관을 깨는 제외하고 문제가 발생하지 않을 것입니다.-Rmvcp-R-Rmv

당신은 어떤 설명을 알고 있습니까? 오래 전에 이유가 있었을 수 있습니까?


추가 질문 : 왜 coreutils 개발자 cp가 기본적으로 복사 디렉토리를 재귀 적으로 작성하지 않습니까?



답변

디렉토리는 개념적으로 이름 목록과 해당 이름이 가리키는 inode 번호를 포함하는 특수한 “파일”입니다. 일부 이름은 하위 디렉토리 일 수 있습니다. ..부모 디렉토리를 가리키는 특별한 항목 이 있습니다.

따라서 파일 이름을 명확하게 변경하는 것은 쉽습니다. 디렉토리 항목의 이름 만 변경하면됩니다. 파일이 실제로 파일인지 또는 다른 디렉토리의 내용을 저장하는 데 사용되는 “파일”인지 여부를 유지합니다. 실제로 동일한 renamesyscall이 둘 다 수행합니다.

그러나 복사는 훨씬 덜 간단한 작업입니다. 당신은 할 수 단지 디렉토리 “파일을”복사,하지만 당신은 파일 (그들은 하드 링크 것) 동일한 두 개의 디렉토리가 것입니다. 디렉토리에 대한 하드 링크를 허용하는 시스템이 있다면, 그렇게 할 수 있지만, 최신 시스템에서는 루트가 아닌 루트를 허용하지 않으므로 각 서브 디렉토리에 대해 해당 사본을 작성해야합니다. 당신은 실제로 요청할 수 있습니다 cp이 행동 cp -lR: -l하드 링크, -R그 재귀하십시오.

그러나 모든 것을 연결된 상태로 두는 것은 당신이 원하는 것이 아닐 것입니다. 대신 cp각 파일을 복사 하려고 합니다. 상당히 비싼 작업입니다. 각 파일을 메모리로 읽고 두 번째 위치에서 디스크에 다시 써야합니다. 실제로 파일을 열고, 읽고, 쓰고, 닫으려면 몇 번의 syscall이 필요하며 각 파일마다 반복해야합니다.

전통적인 파일 시스템도 디스크에서 이런 방식으로 작동합니다. 각 파일을 개별적으로 복사하여 복사하는 것 외에 여러 파일을 복사하는 방법은 없으며 기본 명령 줄 유틸리티를 디자인 할 때 사용 된 파일 시스템 유형입니다.


답변

다른 질문을하면서 시작하겠습니다 :

차이점은 무엇이며 cp그리고 cp -R?

-R플래그가 없으면 파일을 복사하는 것이 가능합니다. 누군가가 재귀 적으로 디렉토리를 복사하지 않으려는 경우가 드물기 때문입니다. 구조. 그것이 사람들이 원하는 ln것은 아니며, 실제로 이것을 수행하는 별도의 프로그램이 있기 때문에 ( 비재 귀적) 디렉토리의 사본은 허용되지 않습니다.

그렇다면 mv과 의 차이점은 무엇입니까 mv -R?

mv a b디렉토리에서 단일 항목의 이름 만 바꾸면 디렉토리가 mved이면 해당 내용도 자동으로 이동합니다. 그런 의미에서, mv이미 재귀 적 속성을 제공으로부터 예를 들어, 이름이 디렉토리에있는 모든 항목의 “이름 바꾸기”즉, a/1b/1. mv, 즉 디렉토리 이름을 변경하는 그렇게하지 않습니다 a에를 b하지만, 유지 a/1a/1, 그들이 뭔가를 이동를 참조 할 때 사람들이 이해하는 것이 아니다 : 당신이 찬장을 이동하는 경우는, 찬장의 내용도 이동됩니다. 내용없이 디렉토리를 이동하는 다른 작업도 이미 사용 가능합니다 mkdir.


답변

일반적으로 유닉스 로직을 망 쳤을 때 나는 Plan9를보고 유닉스 발명자들이 몇 년 후 이전 버전과의 호환성을 유지하면서 어떻게 동일한 작업을 구현했는지 살펴 봅니다.

따라서 Plan9는 파일로만 작동하는 도구 cpmv툴을 제공 합니다.

`cp f1 f2` creates f2 and copies f1's contents into it.
`mv f1 f2` renames f1 to f2 if f1 and f2 are in the same dir
           does `cp f1 f2 && rm f1` else
           can rename dirs (`mv d1 d2`) but will not move dir to another dir.

디렉토리를 복사하기 위해 dircp실제로는 @{cd fromdir && tar c .} | @{cd todir && tar xT}(rc 셸 구문)

디렉토리를 이동하기 위해 나는 단지 dircp d1 d2 && rm -r d1

파일 작업 만 제한 cp하고 mv(디렉이 아님) 이 결정 은 디스크 작업을 더 명확하게하고 tar파일 트리 복사에 사용 하는 것은 이해하고 스크립팅에 매우 편안하다고 생각합니다.


답변