[bash] 메타 문자 주위에 공백이 필요한 이유는 무엇입니까?

몇 달 전에 나는 팔에 포크 폭탄 을 문신했고 , 공백없이 건너 뛰었습니다. 그러나 셸에서 실행할 때 때때로 (항상 그런 것은 아닙니다) 포크 폭탄을 시작하지는 않지만 구문 오류가 발생합니다.

bash: syntax error near unexpected token `{:'

어제는 친구의 그것을 실행하려고 할 때 무슨 일이 있었 배쉬 쉘, 그리고 나는 공백을 추가하고 갑자기, 일을 :(){ :|:& };:대신:(){:|:&};:

공백이 중요합니까? 팔에 구문 오류가 있었나요?!

항상 zsh 에서는 작동 하지만 Bash에서는 작동 하지 않는 것 같습니다 .

관련 질문 은 공백에 대해 아무 것도 설명하지 않습니다. 실제로 내 질문입니다. Bash가 공백을 올바르게 구문 분석하려면 왜 공백이 필요합니까?



답변

BASH에는 토큰을 구분하는 문자 목록이 있습니다. 이러한 문자라고 메타 문자 가 있고 |, &, ;, (, ), <, >, 공간 . 반면 중괄호 ( {})는 단어를 구성하는 일반 문자 일뿐입니다.

메타 문자 }이기 때문에 두 번째 공백을 생략하면 됩니다 &. 따라서 문신에는 하나 이상의 공백 문자가 있어야합니다.

:(){ :|:&};:


답변

그냥 문신

#!/bin/zsh

그 위에 shebang 그리고 당신은 괜찮을거야.


답변

중괄호는 특수 기호보다 홀수 키워드와 비슷하며 공백이 필요합니다. 예를 들어 괄호와 다릅니다. 비교:

(ls)

작동하며

{ls}

라는 이름의 명령을 찾습니다 {ls}. 작동하려면 다음과 같아야합니다.

{ ls; }

세미콜론은에 대한 매개 변수로 닫는 중괄호가 중지됩니다 ls.

공간 문자가 다소 좁은 비례 글꼴을 사용한다고 사람들에게 알리기 만하면됩니다.


답변

문신 글꼴에서 쉽게 볼 수는 없지만 실제로는 중괄호와 콜론 사이에 BOM (Byte-Order Mark)이 있습니다. . 이것은 세 가지 명백한 가능성을 남깁니다.

  1. 코드를 작성할 때 BOM을 입력하지 못했습니다. 결과는 GIGO의 명백한 적용입니다. 쉘은 단순히 실패한 기록에없는 BOM을 인식하지 못합니다.
  2. 껍질이 너무 낡았습니다. 유니 코드 문자를 인식하지 못하므로 BOM (및 기타 모든 유니 코드 문자)은 어디에서나 BOM이 아닌 파일의 시작이 폭이 0이 아닌 공백으로 취급 되더라도 BOM (또는 다른 모든 유니 코드 문자)은 완전히 무시됩니다. .
  3. 껍질이 너무 새롭습니다. BOM을 ZWNBS로 사용하는 것은 더 이상 사용되지 않으며, 작성자는이 사용이 더 이상 허용되지 않는 향후 유니 코드 버전을 구현했습니다.

답변

그런 다음 공백을 추가하고 갑자기 작동했습니다 …

쉘이 구문 분석하는 방식 때문입니다. 함수 정의가 시작된 후, 즉 뒤에 공백이 필요합니다 {.

foo() { echo hey& }
foo() { echo hey&}
foo(){ echo hey&}

유효합니다. 반면에

foo() {echo hey&}

그렇지 않습니다.


실제로 다음과 같은 문신이 필요합니다.

여기에 이미지 설명을 입력하십시오


로부터 소스 :

  /* We ignore an open brace surrounded by whitespace, and also
     an open brace followed immediately by a close brace preceded
     by whitespace.  */

(가) 뒤에 공백을 생략 {원인 {echo하나의 토큰으로 해석 될 수 있습니다.


동등한 형태

:(){ :|:& };:

될 것이다

:(){
:|:& };:

{대체 버전 에는 공백이 없지만 줄 바꿈으로 인해 셸 {이 토큰 으로 인식 됩니다.


답변