나는 묻고 싶다:
echo {1,2,3}
예상되는 동작인 1 2 3으로 확장하고 에서 까지의 모든 숫자를 인쇄할 것으로 예상할 때 echo [[:digit:]]
반환되는 이유는 무엇 입니까 ?[[:digit:]]
0
9
답변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
둘 다 쉘로 확장됩니다.ls
echo
, 실행하는 명령이 , 또는 , 또는 인지는 중요하지 않습니다 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