globstar는 언제 심볼릭 링크 디렉토리로 내려갑니까?

globstar는 언제 심볼릭 링크 디렉토리로 내려갑니까?

존재하다우분투 포스트에 물어보세요, 설정되지 않은 경우 globstar를 사용하여 파일을 찾습니다 PATH.

$ shopt -s globstar; for v in /**/vim; do [[ -x $v && -f $v ]] && echo "$v"; done
/etc/alternatives/vim
/usr/bin/vim
/usr/bin/X11/vim

지금 생각해보면 이 출력은 좀 이상한 것 같습니다. /usr/bin/X11심볼릭 링크입니다 /usr/bin.

$ readlink /usr/bin/X11
.

따라서 s 의 무한 재귀가 있지만 X11출력에는 첫 번째 재귀만 나타납니다. 이상한 점은 a 가 /usr/**전혀 떨어지지 않는다는 것입니다.X11

$ printf "%s\n" /usr/bin/** | grep X11
/usr/bin/X11

첫 번째 출력과 마지막 출력을 어떻게 조정하나요?


댓글에서:

Ubuntu 16.04에서 Bash 버전 4.4.18(1)을 사용하고 있습니다.

답변1

tl;dr - Bash 확장은 무한 심볼릭 링크 루프(in bash >= 4.3)를 방지하기 위해 복잡하며 귀하와 나는 둘 다 귀하가 게시한 명령에서 수행 중인 작업을 오해했습니다.

bash >= 4.3나는 당신이 에서 설명하는 것을 재현할 수 없기 때문에 bash 4.2.46(예상대로) 재귀 한계에 도달할 때까지 반복한다고 가정합니다 .

이것을 잠시 동안 응시하고 상황을 시뮬레이션하기 위해 테스트 디렉토리를 설정하십시오. 핵심은 각 예에서 bash 확장이 발생하는 방식입니다. 확장자가 뒤에 오는지 여부에 따라 다르게 동작합니다 /. 그리고 우리 영장류의 경우 이와 같은 예를 볼 때 이 시점에서 인지적 부조화가 있습니다.
~에서bash shopt에 대한 문서:

globstar
설정되면 파일 이름 확장 컨텍스트에 사용되는 패턴 "**"은 모든 파일과 0개 이상의 디렉터리 및 하위 디렉터리와 일치합니다. 패턴 뒤에 "/"가 오면 디렉터리와 하위 디렉터리만 일치합니다.

여기에 설명하기 위한 테스트 설정이 있습니다.

$ mkdir -p test/nested
$ cd test
$ touch sneaky
$ touch nested/sneaky
$ cd nested
$ ln -s . looper
$ cd ..

다음과 같은 디렉토리 구조를 생성합니다.

test/
  - sneaky
  - nested/
    - sneaky
    - looper -> ./

이는 내 테스트 디렉터리에서 찾은 내용을 복제합니다.

$ for apath in ../**/sneaky; do echo "$apath"; done   
../test/nested/looper/sneaky                                                                                                                                                                 
../test/nested/sneaky
../test/sneaky

$ printf "%s\n" ../** | grep sneaky
../test/nested/sneaky
../test/sneaky

첫 번째 예에서 glob은 으로 확장됩니다 . glob 뒤에는 a가 있으므로 (test/nested/looper, test/nested, test)링크를 따르지 않고 중지됩니다.looper/

그런 다음 여기에 추가하여 /sneaky컬렉션을 얻습니다 (test/nested/looper/sneaky, test/nested/sneaky, test/sneaky).

두 번째 예에서 glob은 다음으로 확장됩니다 (test/nested/looper, test/nested/sneaky, test/nested, test/sneaky, test)( 삭제하여 이를 확인할 수 있음 | grep sneaky).

다시 말하지만, 이 확장은 링크를 따르지 않지만 looper이 경우에는 추가하지 않으므로 결과에서 제거됩니다 /sneaky.../test/nested/looper/sneaky

반면에 우리는 ../test/nested/sneakyglob ../test/sneaky다음에/

관련 정보