bash extglob: 패턴 목록의 패턴 순서가 중요합니까?

bash extglob: 패턴 목록의 패턴 순서가 중요합니까?

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/

따라서 대답은 하위 패턴 순서가 중요하지도 중요하지도 않다는 것입니다. 그러나 마지막 항목이 "."일 때 버그가 문제를 일으킬 수 있는 것처럼 보입니다.

관련 정보