지원 확장

지원 확장

나는 그것이 {중괄호 확장과 함께 작동한다는 것을 알았습니다.

echo {1..8}

또는 명령 그룹에서:

{ls;echo hi}

Bash는 차이점을 어떻게 알 수 있습니까?

답변1

간단한 이유는 문자가 존재하기 때문입니다: space.

브레이크 확장은 (인용되지 않은) 공백을 처리하지 않습니다.

목록에는 {...}(인용되지 않은) 공백이 필요합니다.

더 자세한 답변은쉘이 명령줄을 구문 분석하는 방법.


명령줄을 구문 분석(이해)하는 첫 번째 단계는 명령줄을 여러 부분으로 나누는 것입니다.
이러한 부분(종종 단어 또는 토큰이라고 함)은 각 메타 문자에서 명령줄을 나누어 생성됩니다.링크에서:

  1. 명령을 고정된 메타 문자 집합(SPACE, TAB, NEWLINE, ;, (,), <, >, | 및 &)으로 구분된 토큰으로 분할합니다. 토큰 유형에는 단어, 키워드, I/O 리디렉터 및 세미콜론이 포함됩니다.

메타문자: spacetabenter;,<>|&.

분할 후 단어는 특정 유형을 가질 수 있습니다(셸에서 이해하는 대로).

  • 명령 사전 할당:LC=ALL ...
  • 주문하다LC=ALL echo
  • 논쟁LC=ALL echo "hello"
  • 리디렉션LC=ALL echo "hello" >&2

지원 확장

"중괄호로 묶인 문자열"(공백이나 메타문자 제외)이 (위와 같이) 단일 단어인 경우에만인용되지 않음, 이는 "브래킷 확장"의 후보입니다. 내부 구조에 대한 추가 검사는 나중에 수행됩니다.

따라서 이것은 "분기 확장"에 적합하며 , as 또는 (bash에서는 zsh가 다릅니다) {ls,-l}이 될 수 있습니다 .ls -lfirst wordargument

$ {ls,-l}            ### executes `ls -l`
$ echo {ls,-l}       ### prints `ls -l`

그러나 이것은 그렇지 않습니다: {ls ,-l}. Bash는 행을 분할 space하여 두 단어로 구문 분석하고 다음을 실행 {ls합니다 (매개변수 누락).,-l}command not found,-l}

 $ {ls ,-l}
 bash: {ls: command not found

귀하의 행: {ls;echo hi}"지원 연장"이 되지 않습니다. 왜냐하면메타 문자 ;space.

이는 세 부분으로 나누어집니다: {ls새 명령: echo hi}. ;새 명령의 시작을 트리거하는 요소를 알아보세요 . 이 명령은 {ls찾을 수 없으며 다음 명령은 다음을 인쇄합니다 hi}.

$ {ls;echo hi}
bash: {ls: command not found
hi}

다른 명령 뒤에 배치되면 어쨌든 그 뒤에 새 명령이 시작됩니다 ;.

$ echo {ls;echo hi}
{ls
hi}

목록

"복합 명령" 중 하나는 "분기 목록"(내 단어)입니다 { list; }.
보시다시피 공백과 종결자로 정의됩니다 ;. 공백이 필요하며
둘 다 "예약"되어 있으므로;{}성격".

따라서 단어로 인식되려면 메타 문자로 묶어야 합니다(거의 항상: ) space.

포인트 2에서 언급했듯이링크 페이지

  1. 각 명령의 첫 번째 토큰이.... , { 또는 ( 이면 명령이 실제로 복합 명령인지 확인하십시오.

귀하의 예 : {ls;echo hi}목록이 아닙니다.

종결자 ;와 공백이 (적어도) 필요합니다 {. 마지막 단어는 }닫는 단어로 정의됩니다 ;.

여기에 목록이 있습니다 { ls;echo hi; }. 이것은 { ls;echo hi;}또한 (덜 일반적으로 사용되지만 효과적입니다) (도움을 주신 @choroba에게 감사드립니다).

$ { ls;echo hi; }
A-list-of-files
hi

그러나 명령에 대한 인수(쉘은 차이점을 알고 있음)로 오류가 발생합니다.

$ echo { ls;echo hi; }
bash: syntax error near unexpected token `}'

그러나 쉘이 구문 분석하고 있다고 생각하는 것에 주의하십시오.

$ echo { ls;echo hi;
{ ls
hi

답변2

block {은 쉘 키워드이므로 다음 단어와 공백으로 구분해야 하며 중괄호 확장에는 공백이 있을 수 없습니다(중괄호 확장 공백이 필요한 경우 이스케이프해야 합니다: ) echo {\ ,a}{b,c}.

명령 시작 부분에 중괄호 확장을 사용할 수 있습니다.

{ls,.}  # expands to "ls ."

그러나 확장 전에 그룹화된 명령의 구문 분석이 발생하므로 이를 사용하여 블록으로 확장할 수는 없습니다.

echo {'{ ls','.;}'}  # { ls .;}
{'{ ls','.;}'}       # bash: { ls: No such file or directory

답변3

명령줄의 구문을 확인하여 이를 알 수 있습니다. 마찬가지로 표현식에서 echo echo첫 번째 에코는 명령으로 처리되어야 하고 두 번째 에코는 첫 번째 에코에 대한 인수로 처리되어야 한다는 것을 알고 있습니다.

{ cmd; }Bash에서는 공백과 세미콜론이 있어야 하므로 매우 간단합니다 . 그러나 예를 들어 zsh에서는 필요하지 않지만 {}셸의 컨텍스트를 분석하면 해당 콘텐츠가 어떻게 처리되어야 하는지 알 수 있습니다.

다음을 고려하세요:

alias 1..3=date
{ 1..3; }    #in bash
{1..3}       #in zsh

둘 다 현재 날짜를 반환하지만

echo {1..3}

Return, 1 2 3쉘은 {}command 의 매개변수를 알고 있으므로 echo확장되어야 합니다.

답변4

첫째, 복합 중괄호는 단어 자체여야 하며 명령줄의 첫 번째 단어여야 합니다.

echo { these braces are just words }

둘째, 단일 중괄호는 특별하지 않습니다(위에 표시된 대로). 빈 중괄호도 특별하지 않습니다.

echo {} # just the token {}: familiar from the find command

쉼표가 없는 것은 그 자체일 뿐입니다.

echo {abc} # just {abc}

이것이 행동이 시작되는 곳입니다.

echo {a,b} # braces disappear, a b results.

{...}따라서 기본적으로 중괄호 확장이 작동하려면 최소한 하나의 인스턴스와 최소한 하나의 쉼표가 있는 단어(공백의 필드로 분할되지 않음)가 필요합니다 .

이것할 수 있는그건 그렇고, 명령줄의 첫 번째 단어는 다음과 같습니다.

{ls,-l} .   # just "ls -l ."

관련 정보