"shopt -s dotglob"을 사용하는 대신 이름이 점(마침표)으로 시작하는 디렉터리를 "명시적으로" 일치시키는 Bash 패턴이 있습니까?

"shopt -s dotglob"을 사용하는 대신 이름이 점(마침표)으로 시작하는 디렉터리를 "명시적으로" 일치시키는 Bash 패턴이 있습니까?

파일 이름과 일치하는 패턴을 구성할 때 해당 문자를 "명시적으로"(즉, 사용하지 않고) 일치시키려면 /home/user/project/.git어떻게 해야 합니까 ?.shopt -s dotglob

설명서는 다음 위치에 있습니다.https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html상태:

파일 이름 확장에 패턴이 사용되는 경우 쉘 옵션 dotglob이 설정되지 않은 한 파일 이름 시작 부분이나 슬래시 바로 뒤의 "." 문자가 명시적으로 일치해야 합니다.

"명확한 일치"란 정확히 무엇을 의미합니까?

다시 말하지만,http://www.tldp.org/LDP/abs/html/globbingref.html( Notes마지막 부분에서) 동일한 개념을 해결합니다.

파일 이름 확장은 도트 파일과 일치할 수 있지만 패턴에 도트가 리터럴 문자로 명시적으로 포함된 경우에만 가능합니다.

이 참고 사항은 다음 예를 제공합니다.

~/[.]bashrc    #  Will not expand to ~/.bashrc
~/?bashrc      #  Neither will this.
               #  Wild cards and metacharacters will NOT
               #+ expand to a dot in globbing.

~/.[b]ashrc    #  Will expand to ~/.bashrc
~/.ba?hrc      #  Likewise.
~/.bashr*      #  Likewise.

"점 파일"을 포함하도록 확장된 마지막 세 가지 예제의 내부 작동을 이해할 수 없습니다.

b구체적으로, 예제에서 괄호 안에 넣어 "명시적" 일치 항목을 만들려면 어떻게 해야 합니까 ? 다음 예는 나에게 더 모호합니다. 문자와 전혀 관련이 없는 것처럼 보이는 방식으로 패턴을 조작하면 패턴이 일치하는 결과를 얻을 수 있다는 것을 이해할 수 없습니다..~/.[b]ashrc.

내가 왜 그것을 피하고 싶은지에 대한 이 질문의 원동력은 shopt -s dotglob내가 다른 프로그램의 구성 파일에 사용하기 위해 이러한 패턴을 작성하고 있다는 사실에서 비롯됩니다. "숨겨진 디렉터리" 등이 포함된 경로를 제외하고 싶은데 , 어떤 방식으로든 이를 지정할 .git수 있는지 잘 모르겠습니다 .dotglob

.본질적으로: "명시적"으로 문자를 일치시키는 가장 쉬운 방법은 무엇입니까? 다음 문자를 괄호 안에 넣으면 "작동하게 됩니다". 하지만 이 접근 방식을 사용하면 "어둠 속에서 촬영"하는 것처럼 느껴지는 이유를 알고 싶습니다.

이와 관련하여 잠재적인 행동에 대한 설명을 주시면 감사하겠습니다.

다음을 추가하도록 편집되었습니다.

처음에는 관련성이 없어 보이지만 사람들이 내 사용 사례의 구체적인 세부 사항에 관심을 보이는 것 같아서 추가로 설명하겠습니다.

저는 이라는 호스트 기반 침입 탐지 소프트웨어를 사용하고 있습니다 Samhain. Samhain은 특정 사용자 지정 구성 매개변수에 따라 파일 시스템이 수정될 때마다 "경고"합니다.

아니요.git디렉터리(일부 상위 디렉터리에 있음) 내부의 파일이 생성/수정/삭제될 때 Samhain이 경고하도록 하려고 합니다. Samhain에서는 "규칙 무시"를 정의하여 이러한 유형의 제외를 수행합니다. 이러한 규칙의 구체적인 사양은 다음 항목에 설명되어 있습니다.http://www.la-samhna.de/samhain/manual/filedef.html, 존재하다 4.2. File/directory specification.

간단히 말해서:

Wildcard patterns ('*', '?', '[...]') as in shell globbing are supported for paths. The leading '/' is mandatory.

그래서 관련 디렉터리와 일치하는 "무시 규칙"을 작성하려고 했는데 .git, 이로 인해 실제로 Samhain은 해당 디렉터리를 모니터링 활동에서 제외하게 되었습니다.

처음에는 다음과 같이 시도했습니다.

[IgnoreAll]
dir = -1/home/user/project/*/*/.git

이것은 작동하지 않습니다. Samhain은 이러한 디렉토리의 파일이 변경될 때마다 계속 경고합니다 .git.

위에서 인용한 예를 찾은 후 다음을 시도했습니다.

dir = -1/home/user/project/*/*/.[g]it

이 변경으로 인해 Samhain은 필요에 따라 이러한 파일을 무시합니다.

이 질문을 게시할 때 저는 왜 이 변경 사항이 원하는 효과를 얻었는지 이해하고 싶었습니다.

원래 사용하려고 했던 패턴이 "echo"로 테스트했을 때 문제의 디렉토리와 일치했다는 점을 고려하면 .git덜 어리석은 느낌이 듭니다 .

echo /home/user/project/*/*/.git

따라서 제가 Bash의 패턴 일치, 와일드카드 또는 파일 이름 확장에 대한 기본 지식을 오해한 것은 아닙니다. 대신 이 경우 Samhain이 패턴 일치를 구현하는 방식에 미묘한 차이가 있는 것으로 보입니다.

Samhain의 프로필에 적용했을 때 이것이 왜 작동하지 않는지 모르겠습니다(분명히). 이 편집 내용을 보면 누군가 설명할 수 있을 것입니다.

답변1

파일 이름 확장에 패턴이 사용되는 경우 쉘 옵션 dotglob이 설정되지 않은 한 파일 이름 시작 부분이나 슬래시 바로 뒤의 "." 문자가 명시적으로 일치해야 합니다.

이는 단순히 glob을 의미하며 파일 이름 시작 부분의 a와 일치하지 *않습니다 . 파일 이름 시작 부분에 a를 일치시키려면 glob을 사용할 수 없으며 명시적으로 입력해야 합니다. 예를 들어:?[...]...

$ echo ????
Work
$ echo .???
.gem .pki .ssh .vim

그리고 다른 질문에 답하려면:

b구체적으로, 예제에서 괄호 안에 넣어 "명시적" 일치 항목을 만들려면 어떻게 해야 합니까 ?.~/.[b]ashrc

glob 모드를 사용한다고 해서 꼭 그런 것은 아닙니다.모두패턴은 더 이상 "명확"하지 않습니다. 예를 들어 에서는 ~/.[b]ashrc문자가 /.ashrc명시적으로 일치됩니다. 그러나 [b]이는 전역 패턴이며 명시적인 일치는 아닙니다. (기술적으로 ~물결표 확장이고 전역 확장 이전에 수행되므로 명시적 일치도 마찬가지입니다.) 그러나 .,하다명시적 매칭이 바로 ~/.[b]ashrcmatch 입니다 ~/.bashrc.

~/?[b]ashrc비교 를 위해,아니요match ~/.bashrc, .더 이상 명시적인 일치 항목이 없기 때문입니다.

답변2

먼저, 경로명 패턴에서 , [b]?등이 무엇을 의미하는지 알고 있다고 가정합니다. *(그렇지 않다면 좀 더 연구해 보세요.)

다른 사람들이 말한 것을 반복할 위험을 무릅쓰고 당신은 그것을 지나치게 생각하고 있는 것입니다. 문자열을 포함하는 패턴 /. (예:/ 그 다음에.)에는 점이 리터럴 문자로 명시적으로 포함됩니다. 요점은 [b], ?및/또는 *현재 일어나고 있습니다.뒤쪽에이것. 패턴이 도트 파일과 일치할 수 있는지 여부에는 영향을 주지 않습니다. 마지막 세 가지 예는 예제로 제공됩니다.무늬 (즉, 일반 파일/경로 이름뿐만 아니라 여러 파일/경로 이름과 일치하거나 전혀 일치하지 않는 것)은 ~/.bashrc처음 두 개가 아닌 일치합니다.회의일치하는 ~/.bashrc경우.특별한 대우는 없습니다.

그렇다면 당신의 진짜 문제는 무엇입니까?

...다른 프로그램의 구성 파일에 사용하기 위해 이러한 패턴을 작성하고 있습니다. "숨겨진 디렉터리" 등이 포함된 경로를 제외하고 싶은데 , 어떤 방식으로든 이를 지정할 .git수 있는지 잘 모르겠습니다 .dotglob

chown모든 파일/디렉토리(예: 또는 ) 에 대해 일부 작업을 수행하고 싶은 것 같습니다.cp와는 별개로점으로 시작합니다. 하지만 귀하의 코드는 다른 사람의 스크립트에서 사용됩니다(다음을 통해)..또는 명령), 스크립트가 "숨겨진" 파일을 포함한 모든 파일로 확장 되도록 설정될 수 있으므로 source이 작업을 수행하기가 두려울 수 있습니다 . 그리고 기존 스크립트의 기능을 중단하고 싶지 않기 때문에 닫고 싶지 않을 것입니다 .your_command *dotglob*dotglob

  1. 더 스마트한 와일드카드(경로 이름 확장 패턴)를 사용하세요.

    와일드카드(일명 와일드카드)에 대해 배웠기를 바랍니다. 예를 들어 모든 문자 와 [abc]일치합니다 a. 예를 들어 문자열 은 , 및 와  일치합니다 . (예를 들어 및 와 같이 범위와 함께 자주 사용됩니다 .) 음, 한 가지 특별한 경우는 모든 문자와 일치합니다 .bcc[aou]tcatcotcutd[iou]gdigdogdug[a-z][0-9][!abc]와는 별개로 a, b또는 c. 따라서 [!.]*(또는 directory_name/[!.]*)을 사용하여 점이 아닌 문자로 시작하는 이름을 일치시킬 수 있습니다. 역설적이게도 설정하지 않으면 [.](파일 이름 시작 부분에) 점과 일치하지 않지만dotglob[!.]들어오지 못하게 하다설정에 상관없이 포인트입니다  dotglob.

    dotglob이는 설정 여부에 관계없이 동일한 결과를 제공합니다.

  2. dotglob(하위 쉘에서)을 사용하십시오 .

    셸 옵션은 shopt프로세스에 대해 로컬이며 프로세스 속성은 하위 프로세스에서 상위 프로세스로 역방향(위쪽)으로 흐르지 않습니다. 그래서

    (shopt -u dotglob;주문*)
    실행할 수 있습니다your_command나머지 스크립트의 설정 및 동작에는 영향을 주지 않고 숨겨지지 않은 파일에만 적용됩니다.

  3. 사용 dotglob(서브쉘을 사용하지 않고).

    어떤 사람들은 추가 리소스를 사용하기 때문에 서브쉘을 피하는 것을 선호합니다. 그러나 비용은 최소화됩니다(실행 루프에서 수행하지 않는 한).많은번), 이는 별로 좋은 이유가 아닙니다. 서브셸 사용을 피하는 더 좋은 이유 cdumask.

    이런 일이 발생하면 일시적으로 전원을 끄고 dotglob나중에 이전 설정을 복원할 수 있습니다.

    또는 shopt dotglob없이 입력하면 해당 옵션의 현재 설정이 보고(표시)됩니다 . ( 그리고-s-udotglobshopt아니요매개변수는 현재 설정을 나열합니다.모두옵션. ) 그에 따라 종료 상태도 설정됩니다. 이 -q플래그는 표시를 억제하므로 다음을 수행할 수 있습니다.

    shopt -q 페널티
    glob_setting=$?을 클릭하세요.
    shopt -u 도트 글로브
    주문*
    if ["$dotglob_setting" = 0]
    그 다음에
        shopt -s 페널티
    필리핀 제도

하지만 기다려..."다른 프로그램의 구성 파일"에 대해 이야기하고 있습니다. 당신이 무슨 말을하는거야? 유사한 파일을 작성하거나 수정하는 것에 대해 이야기하는 경우 ignore=*.o파일을 처리하는 모든 프로그램에서 파일을 처리(및 해석)하므로 전체적인 질문은 의미가 없습니다.그 프로그램그것을 해석하는 방법을 결정할 것입니다 *. 쉘은 그것과 아무 관련이 없습니다.


자, 이제 문제가 무엇인지 더 잘 알 수 있게 되었습니다.

간단히 말해서, 당신이 보고 있는 행동은 말이 되지 않습니다. .git디렉터리가 존재하는 경우 디렉터리를 정확하게(문자 그대로) 지정 .git 하고 와일드카드/전역 패턴을 사용하여 지정하면 .[g]it 동작이 동일해야 합니다.

더 긴 답변: 저는 제 답변의 첫 번째 버전의 마지막 단락을 지지합니다. Samhain은 정책 구성 파일을 읽고 구문 분석 중입니다. 아마도 구성 파일의 와일드카드를 해석하기 위해 셸을 사용하지만 내부적으로는 그렇게 하는 것 같습니다.

그리고 "쉘을 사용하는 것"이라면 어떤 쉘을 사용하고 있습니까? Bash가 아닌 많은 시스템에서 /bin/sh. 경로 이름 확장 패턴(예: 와일드카드) 측면에서 기본 동작은 동일해야 하지만 일단 현관에서 벗어나면 늪에 빠지게 됩니다. 쉘에 대한 POSIX 사양에는 command 도 없으며 (내가 아는 한) 이를 확장 shopt할 방법이 없습니다.*모두파일(숨겨지지 않은 파일뿐만 아니라).

당신이 느낀다면쓰레기이에 대해 더 많은 시간을 할애하여 Samhain 구성 파일을 넣고 해당  /home/user/project/*파일이 모든 파일로 해석되는지 아니면 숨기지 않은 파일로 해석되는지 확인할 수 있습니다. 그것이 모든 파일로 해석된다면 우리는 결론을 내릴 수 있습니다

  1. Samhain은 확장된 와일드카드를 사용하지 않습니다 /bin/sh.
  2. 와일드카드 사용에 대한 표준 기본 규칙(질문에서 자세히 논의한 규칙)이 없습니다.
  3. "Path는 쉘 와일드카드에서 와일드카드 패턴('*', '?', '[...]')을 지원합니다."라고 적혀 있기 때문에 문서가 잘못되었거나 기껏해야 불완전하고 오해의 소지가 있습니다. 동작)은 *모든 파일을 의미합니다.
  4. 그것가능한와일드카드를 확장하려면 모드에서 bash를 사용하세요 dotglob. 그러나 내가 말했듯이, 내가 아는 쉘의 일반적인 동작 .git과 일치하지 않습니다. .[g]it거의 확실하게 자체 와일드카드 코드가 있습니다.

그러나 그럼에도 불구하고 저는 귀하의 결론이 정확하다고 자신있게 말할 수 있다고 믿습니다. Samhain은 IgnoreAll사양에서 와일드카드를 처리하는 데 오류가 있습니다. 공급업체에 버그 보고서를 제출할 수도 있습니다. 아니면 해결책을 찾았으니 이제 잊어버리셔도 됩니다.

관련 정보