Bash 매뉴얼에 따르면, 활성화된 경우 이 패턴은 extglob
(구분) @(pattern-list)
의 모든 패턴과 일치 해야 합니다. 여기서는 예상대로 작동합니다.pattern-list
|
$ shopt -s extglob
$ ls -ld /@(.|usr)/@(.|local)/@(.|share)/
drwxr-xr-x 50 root root 4096 Sep 2 16:39 /./././
drwxr-xr-x 12 root root 4096 Oct 15 2018 /usr/././
drwxrwsr-x 10 root staff 4096 Oct 15 2018 /usr/local/./
drwxrwsr-x 10 root staff 4096 Oct 15 2018 /usr/local/share/
drwxr-xr-x 725 root root 20480 Sep 2 16:42 /usr/./share/
그러나 세 가지 패턴 목록 각각에서 대안을 바꾸면 일치해야 하는 대부분의 디렉터리가 사라집니다.
$ ls -ld /@(usr|.)/@(local|.)/@(share|.)/
drwxrwsr-x 10 root staff 4096 Oct 15 2018 /usr/local/share/
존재하지 않는 하위 디렉터리의 경우에도 마찬가지입니다. 여기에서는 작동합니다:
$ ls -ld /@(.|usr)/@(.|foo)/@(.|share)/
drwxr-xr-x 50 root root 4096 Sep 2 16:39 /./././
drwxr-xr-x 12 root root 4096 Oct 15 2018 /usr/././
drwxr-xr-x 725 root root 20480 Sep 2 16:42 /usr/./share/
하지만 여기서는 그렇지 않습니다.
$ ls -ld /@(usr|.)/@(foo|.)/@(share|.)/
ls: cannot access '/@(usr|.)/@(foo|.)/@(share|.)/': No such file or directory
여기서 무슨 일이 일어나고 있는 걸까요? 이 동작이 어딘가에 문서화되어 있나요, 아니면 단순한 버그인가요? (이것은 GNU bash 버전 4.4.12(1)입니다.)
답변1
bash-4.3 이전에는 "." 용어가 일치하지 않았습니다. bash(1), v5.0, 일부에서경로명 확장:
When a pattern is used for pathname expansion, the character ``.'' at the start of a name or immediately following a slash must be matched explicitly, unless the shell option dotglob is set. The filenames ``.'' and ``..'' must always be matched explicitly, even if dotglob is set.
여기서 동작에 대한 설명은 약간 모호하지만아니요"."는 모든 (하위)패턴의 시작 부분에 있어야 함을 의미하며 다음을 통해 증명할 수 있습니다.
$ echo /@(usr|.)/@(local|.)/@(share|.)/
/usr/local/share/
$ echo /@(usr|..)/@(local|..)/@(share|..)/
/../../../ /usr/../../ /usr/local/../ /usr/local/share/
따라서 문제는 "."에만 해당됩니다. “..”가 아닙니다.
나는 이것이 버그라고 믿는다.extglob_skipname()
, while (t = glob_patscan (pp, pe, '|')) { ... }
루프의 218번째 줄부터 이 패턴의 마지막 항목이 올바르게 처리되지 않으므로( 의 선행 "." 억제 논리와 상호작용 skipname()
) "."는 일치하지 않지만 ".."는 일치합니다. ( glob_patscan
일명 Macro Games 덕분입니다 PATSCAN
.)
다음 중 어느 것도 작동합니다.
$ echo /@(usr|.|)/@(local|.|)/@(share|.|)/
/./././ /usr/././ /usr/./share/ /usr/local/./ /usr/local/share/
$ echo /@(usr|.|.)/@(local|.|.)/@(share|.|.)/
/./././ /usr/././ /usr/./share/ /usr/local/./ /usr/local/share/
따라서 대답은 하위 패턴 순서가 중요하지도 중요하지도 않다는 것입니다. 그러나 마지막 항목이 "."일 때 버그가 문제를 일으킬 수 있는 것처럼 보입니다.