경로를 지정하지 않으면 왜 './'를 인쇄해야합니까?


13

경로가 없으면 결과 find로 이어지는 이유는 무엇 ./입니까?

$ find
./file1
./file2
./file3

이것을 인쇄하지 않는 이유는 무엇입니까?

$ find
file1
file2
file3

답변:


16

이유는 GNU의 개발자가 있기 때문에 당신이 볼 이유입니다 선택 에 대해 "합리적인"동작을 제공하는 경로가 지정되지 않은 경우입니다. 반대로 POSIX 는 매개 변수가 선택적이라는 것을 나타내지 않습니다.find find

find유틸리티는 path의해 지정된 각 파일 에서 디렉토리 계층 구조를 재귀 적으로 내려 와서 발생하는 각 파일에 대해 OPERANDS 섹션에 설명 된 기본으로 구성된 부울 식을 평가합니다. 각 경로 피연산자는 모든 후행 <slash>문자를 포함하여 제공된대로 변경되지 않은 상태로 평가됩니다 . 계층에서 만나는 다른 파일에 대한 모든 경로명 은 현재 경로 피연산자 의 연결<slash> , 현재 경로 피연산자가 1로 끝나지 않은 경우 및 경로 피연산자에 상대적인 파일 이름으로 구성됩니다. 상대 부분은 점 또는 점 요소를 포함하지 않아야하며 후행을 포함하지 않아야합니다.<slash>경로 이름 구성 요소 사이 에는 단일 문자 만 있습니다.

각각의 시놉시스에서 차이를 볼 수 있습니다. GNU는 관례대로 옵션 항목을 대괄호로 묶습니다.

find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...]
       [expression]

POSIX는 옵션이 될 수 있음을 나타내지 않습니다.

find [-H|-L] path... [operand_expression...]

GNU 프로그램에서는 다음과 같이 수행됩니다 ftsfind.c.

  만약 (빈)
    {
      / *
       * 여기서는 일부 작업이 수정되므로 임시 변수를 사용합니다
       * 경로가 일시적입니다. 따라서 문자열 상수를 사용하면
       * 우리는 코어 덤프를 얻습니다. 가장 좋은 예는 우리가
       * "find -printf % H"( "find. -printf % H"가 아님).
       * /
      char defaultpath [2] = ".";
      return find (기본 경로);
    }

리터럴 "."은 단순성을 위해 사용됩니다. 그래서 당신은 같은 결과를 볼 수 있습니다

find

find .

POSIX는 주어진 경로 가 결과의 접두사로 사용 되기 때문에 (그리고 연결에 대해서는 위를 참조하십시오 ).

약간의 작업으로 기능이 처음 추가 된 시점을 결정할 수 있습니다. 1996 년에 "findutils"초기 작성에있었습니다 (참조 find.c).

+  /* If no paths are given, default to ".".  */
+  for (i = 1; i < argc && strchr ("-!(),", argv[i][0]) == NULL; i++)
+    process_top_path (argv[i]);
+  if (i == 1)
+    process_top_path (".");
+
+  exit (exit_status);
+}

찾기 3.8에 대한 변경 로그에서 이것은 분명히

Sat Dec 15 19:01:12 1990  David J. MacKenzie  (djm at egypt)

        * find.c (main), util.c (usage): Make directory args optional,
        defaulting to "."

11

일반적으로 파일의 사후 처리를 수행하므로이 경우 파일 이름을로 시작하면 큰 이점이 있습니다 ./. 특히 파일 이름이로 시작 -하면 후속 명령은 해당 파일 이름을 옵션으로 해석 할 수 있습니다. ./그것을 피하십시오.

예를 들어, 다음 파일이있는 디렉토리를 고려하십시오.

$ ls
--link  --no-clobber

이제 파일 이름이 ./앞에 없이 제공된 경우이 명령이 어떻게 작동하는지 상상해보십시오 .

$ find -type f -exec cp -t ../ {} +

우리는 find그 자체로 문제를 설명 할 수 있습니다 . 위와 같은 디렉토리에서 실행 해 봅시다. 다음과 같이 작동합니다.

$ find ./*
./--link
./--no-clobber

다음은 실패합니다 :

$ find *
find: unknown predicate `--link'
Try 'find --help' for more information.

1
말된다. 그러나 왜 '.'를 앞에 붙지 않는지에 대한 의문이 있습니다. 당신이 실행할 때 find *.
nr

@nr 좋은 지적. 나는 그것이 일종의 역사적 호환성을 위해 그런 식으로 행동하기를 기대합니다. 왜 이것이 바람직하지 않은 행동인지에 대한 예를 대답에 추가했습니다.
John1024

3
일부 버전의 file 수요 사용자는 (OS X의 BSD의 발견 등)의 경로를 제공합니다. 따라서 일반적으로 다음과 같이 명시 적으로 말해야합니다 find . -type f .... 거기에서 (GNU find와 같은) 일부 버전의 find는 기본값을 .그대로두고 다른 모든 것을 그대로 둡니다.
ilkkachu

1
그 이유 find *표시되지는 .때문에 *목록의 모든 파일과 폴더 만 제외 .. 수행 echo *하나 또는 두 개의 파일이 포함 된 디렉토리에, 당신은 볼 것이다 .나열되지 않습니다. 따라서 find *확장 된 각 파일 에서 작동합니다. find Desktop/홈 디렉토리에서 말한 것과 같습니다 . 다음과 같이 출력됩니다 :Desktop/foo_bar.txt
Sergiy Kolodyazhnyy

1
@ John1024 : MrigeshThomas Dickey 가이 질문에 올바르게 대답 했다고 생각합니다 . 이 답변은 편리한 find방식으로 동작하는 이유를 설명합니다 . 이런 이유로find 이러한 방식으로 작동하도록 설계된 암시 적 주장을 뒷받침 할 신뢰 할만한
G-Man, 'Reinstate

4

find명령 요구 경로 (들)을 검색 할 수 있습니다. 아무 것도 지정하지 않으면 현재 디렉토리 ( .)를 시작점으로 사용합니다. 마찬가지로 경로를 전달하면 (예 /tmp:) 시작 경로로 간주합니다. 따라서 결과.

현재 디렉토리 인 경우 :

        $ find
or
        $ find .

output:
        ./file1
        ./file2
        ./file3

/tmp디렉토리 인 경우 :

        $ find /tmp

output:
        /tmp/file4
        /tmp/file5

abc현재 디렉토리 아래 디렉토리 인 경우 :

        $ find abc

output:
        abc/file6
        abc/file7

현재 디렉토리 아래에 여러 디렉토리가있는 경우 :

        $ find fu bar

output:
        fu/file10
        fu/file11
        bar/file8
        bar/file9

예, find무엇이든 검색 할 경로가 필요하며 기본 디렉토리는 현재 디렉토리입니다. 문제는 왜 ./file.txt와 동일 할 때 선행을 인쇄 하는가 ./file.txt입니다.
nr

1
찾기가 "."을 추가하지 않습니다. 시작할 때 실제로 "/ tmp" "abc"또는 "."인지 여부에 관계없이 경로로 지정한 것을 추가합니다. 모든 값을 각각 반환합니다.
Mrigesh Priyadarshi

-2

경로를 지정하지 않으면 find명령은 경로를 경로로 가정 ${PWD}하고 출력에 인쇄합니다. 경로를 지정하지 않은 사용자는 find작동 방식을 변경하지 않습니다 . 찾기는 항상 기본적으로 경로와 함께 작동합니다.


1
내가 참조. 당신이 아래를 실행한다면 /tmp, 다음 $PWD입니다 /tmp없습니다 ./.
nr

preceeding을 보려면 /tmp명령을 실행하십시오 find /tmp. 경로를 지정하지 않으면 항상 현재 디렉토리가됩니다../
MelBurslan

1
내가 선행을보고 싶지는 않습니다 /tmp. 그것이 될 수 없습니다 $PWD.
nr

저의 사과 ${PWD}는 잘못된 언어였습니다
MelBurslan

2
아니요, $ PWD를 가정하지 않습니다. 의 출력을 비교 find ., find $PWD그리고 find(경로없이, 당신의 발견은 지원하는 경우).
ilkkachu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.