존재하다우분투 포스트에 물어보세요, 설정되지 않은 경우 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/sneaky
glob ../test/sneaky
다음에/