"cp -ra/.b"가 왜 그렇게 동작하나요?

"cp -ra/.b"가 왜 그렇게 동작하나요?

나는 그렇게 생각했고 , 같은 길이다 a. a/.그러나 나는 그것을 발견했다CP그리고재동기화/.소스 경로에 추가 되면 디렉터리 자체 대신 디렉터리 내용을 복사합니다 . 나도 시도했다 a/inner/..; 이것도 트릭을 수행했습니다.

$ cp -r a b  # Copies dir a into dir b.
$ cp -r a/. b  # Copies files from dir a into dir b.
$ cp -r a/inner/.. b  # Also copies files from dir a into dir b.
$ cd a && cp -r . ../b  # One more way to copy inner files.

나는 이것이 유용하다는 것을 이해합니다. 하지만 이 기능이 표준을 위반하는 것 같아서 약간 혼란스럽습니다.

어떻게 작동하나요? 이 기능이 어딘가에 문서화되어 있나요? 이게 OS의 특징인지,CP아니면 배쉬?

답변1

나는 이것이 유용하다는 것을 이해합니다. 하지만 이 기능이 표준을 위반하는 것 같아서 약간 혼란스럽습니다.

CPa/.에서 로 재귀적으로 복사할 때의 동작은 b"정상적인" 동작과 완벽하게 일치합니다.

기본적으로,CP's는 상위 디렉토리를 생성하지 않습니다. 이는 다음을 사용하여 수정할 수 있습니다.부모스위치:

   --parents
          use full source file name under DIRECTORY

그런데 그게 무슨 뜻인가요?

이는 명령이 실행되는 동안

cp --parents -r some/path/to/source dest

소스 디렉토리의 내용을 에 복사합니다 dest/some/path/to/source.

cp -r some/path/to/source dest

소스 디렉토리의 내용을 에 복사합니다 dest/source.

마찬가지로, 명령

cp -r some/path/to/source/. dest

소스 디렉토리의 내용을 에 복사할 것 dest/.입니다 dest.

생각했는데 a똑같은 a/.길이네요.

a그리고a/. ~이다같은 길. 그러나 주장으로CP, 그것은 단지 문자열입니다.

명령은 다음과 같습니다.

cp --parents -r some/path/to/source dest

그리고

cd some/path/to && cp --parents -r source dest

다르게 행동할 것입니다.


는 어때 cp -r a/inner/.. b? 귀하의 설명을 고려하면 파일을 b/..(즉, 현재 디렉터리)로 복사하면 안 됩니까?

그렇죠. 이는 예외입니다.

적어도 GNU 버전에서는CP, 기본 이름에는 특별한 경우가 있습니다 ...

에서coreutils-8.22/src/cp.c:

          if (parents_option)
            {
              [removed]
            }
          else
            {
              char *arg_base;
              /* Append the last component of 'arg' to 'target_directory'.  */

              ASSIGN_BASENAME_STRDUPA (arg_base, arg);
              /* For 'cp -R source/.. dest', don't copy into 'dest/..'. */
              dst_name = (STREQ (arg_base, "..")
                          ? xstrdup (target_directory)
                          : file_name_concat (target_directory, arg_base,
                                              NULL));
            }

동기는 대상 폴더 외부로 복사하는 것을 피하는 것 같습니다. 이는 – 완벽하게 일치하지만CP다른 모든 경우에 의 행동은 약간 반직관적이며 불쾌한 결과를 초래할 수 있습니다.

결국 누구도 그 명령을 기대하지 않을 것 같아요

cp -r .. ~

자신의 홈 디렉터리 외부에 있는 파일에 영향을 미치려면...

답변2

$ mkdir a b a/inner
$ touch a/a{1..3} b/b{1..3}
$ ls -R
.:
a  b

./a:
a1  a2  a3  inner

./a/inner:

./b:
b1  b2  b3
$ cp a b
cp: omitting directory ‘a’
$ cp a/. b
cp: omitting directory ‘a/.’
$ cp a/inner/.. b
cp: omitting directory ‘a/inner/..’
$ cd a && cp . ../b
cp: omitting directory ‘.’
$ cd ..
$ ls -R
.:
a  b

./a:
a1  a2  a3  inner

./a/inner:

./b:
b1  b2  b3

당신이 말하는 일은 실제로 일어나지 않습니다. 네 가지 cp명령은 아무 작업도 수행하지 않습니다. 아마도 로드됨에 대한 별칭이 있을 수 있습니다 cp. 로 이를 확인할 수 있습니다 alias cp.

답변3

대략 rsync(1), 설명서를 읽어보세요주의하여. "디렉토리의 내용"과 "디렉토리 및 해당 내용"을 의미하기 위해 몇 가지 특이한 규칙을 사용합니다.

cp(1)및 기타 Linux 명령의 경우핵심level aa/.심지어는 a/inner/..정확히 동일한 디렉토리를 참조합니다. 이는 애플리케이션이 자체적으로 구문 분석하여 이상한 의미를 부여할 수 없다는 의미는 아니지만 올바른 작업을 수행할 커널에 문자열을 전달하는 것이 더 쉽습니다.

답변4

내가 올바르게 기억한다면 나는 . 이 경우 *와 유사하게 작동합니다. 본질적으로 와일드카드 문자입니다.

관련 정보