echo [[:digit:]]에 예상치 못한 동작이 있습니다.

echo [[:digit:]]에 예상치 못한 동작이 있습니다.

나는 묻고 싶다:

echo {1,2,3}예상되는 동작인 1 2 3으로 확장하고 에서 까지의 모든 숫자를 인쇄할 것으로 예상할 때 echo [[:digit:]]반환되는 이유는 무엇 입니까 ?[[:digit:]]09

답변1

왜냐하면 그것들은 서로 다른 것이기 때문입니다. 이것은 {1,2,3}예이다버팀대 확장. 이건 {1,2,3}연장됐어쉘을 통해, echo보기도 전에요. 다음 명령을 사용하면 어떤 일이 발생하는지 확인할 수 있습니다 set -x.

$ set -x
$ echo {1,2,3}
+ echo 1 2 3
1 2 3

보시다시피 명령은 echo {1,2,3}다음과 같이 확장됩니다.

echo 1 2 3

그러나 [[:digit:]]그것은POSIX 문자 클래스. 건네주면 echo쉘에서도 먼저 처리하지만 이번에는 로 처리됩니다.쉘 볼. 실행하는 것과 동일하게 작동하며 echo *현재 디렉터리의 모든 파일을 인쇄합니다. 그러나 [[:digit:]]어떤 숫자와도 일치할 수 있는 쉘 글로브입니다. 이제 bash에서 쉘 glob이 아무것도 일치하지 않으면 자체적으로 확장됩니다.

$ echo /this*matches*no*files
+ echo '/this*matches*no*files'
/this*matches*no*files

glob이 무엇인가와 일치하면 다음과 같이 인쇄됩니다:

$ echo /e*c
+ echo /etc
/etc

두 경우 모두 echo쉘이 인쇄하라고 지시하는 것은 무엇이든 인쇄하지만, 두 번째 경우에는 glob이 무언가( /etc)와 일치하므로 그것을 인쇄하라는 지시를 받습니다.

[[:digit:]]따라서 이름이 한 자리 숫자(일치하는 숫자)로 구성된 파일이나 디렉터리가 없으므로 glob은 자체적으로 확장되어 다음을 얻습니다.

$ echo [[:digit:]]
[[:digit:]]

이제 다음과 같은 파일을 생성 5하고 동일한 명령을 실행해 보십시오.

$ echo [[:digit:]]
5

일치하는 파일이 여러 개 있는 경우:

$ touch 1 5       
$ echo [[:digit:]]
1 5

이는 man bash이 동작을 끄는 옵션에 대한 설명에 (다소) 문서화되어 있습니다.nullglob

nullglob
    If  set,  bash allows patterns which match no files (see
    Pathname Expansion above) to expand to  a  null  string,
    rather than themselves.

이 옵션을 설정하는 경우:

$ rm 1 5
$ shopt -s nullglob
$ echo [[:digit:]]  ## prints nothing

$ 

답변2

{1,2,3}버팀대 확장, 의미에 관계없이 나열된 단어로 확장됩니다.

[...]는 다음 용도로 사용되는 문자 그룹입니다.파일 이름 확장자(또는 와일드카드 또는 와일드카드)는 별표 *및 물음표 와 유사합니다 ?. 여기에 나열된 단일 문자 또는 명명된 그룹의 구성원인 문자(예: [:digit:]나열된 문자 중 하나)와 일치합니다. 대부분의 쉘의 기본 동작은 일치하는 파일이 없는 경우 와일드카드를 그대로 두는 것입니다.

(와일드카드/패턴을 일치시키려는 문자열 세트로 실제로 변환할 수는 없습니다. 별표는 모든 길이의 문자열과 일치할 수 있으므로 이를 포함하는 패턴을 확장하면 무한한 문자열 목록이 생성됩니다.)

그래서:

$ bash -c 'echo [[:digit:]]'           # bash leaves it as-is
[[:digit:]]
$ zsh -c 'echo [[:digit:]]'            # zsh by default complains if no match
zsh:1: no matches found: [[:digit:]]
$ touch 1 3 d i g t
$ bash -c 'echo [[:digit:]]'           # now there are two matches
1 3                                    # note that d, i, g and t do NOT match

하지만 여전히:

$ bash -c 'echo {1,2,3}'
1 2 3

둘 다 쉘로 확장됩니다.lsecho, 실행하는 명령이 , 또는 , 또는 인지는 중요하지 않습니다 rm. 또한 다음 중 하나라도 참조되면 확장되지 않습니다.

$ bash -c 'echo "[[:digit:]]"'         # even though matching files still exist
[[:digit:]]
$ bash -c 'echo "{1,2,3}"'
{1,2,3}

답변3

{1,2,3}( {1..3}예 를 들어버팀대 확장. 명령이 실행되기 전에 쉘에 의해 해석됩니다.

[[:digit:]]패턴 매칭토큰이지만 해당 패턴과 일치하는 파일의 위치에서는 사용하고 있지 않습니다. 일치 항목 없이 패턴 일치를 사용하면 자체적으로 확장됩니다.

$ echo [[:digit:]]; touch 3; echo [[:digit:]]
[[:digit:]]
3

관련 정보