Bash 스크립트: 공백 사용

Bash 스크립트: 공백 사용

나는 이 사이트에서 웹 검색과 검색을 시도했지만 bash의 문자열에 공백을 사용하는 것과 관련된 문제만 발견했습니다. 그러나 올바른 사용법(필수 사항과 그 반대)을 더 잘 기억할 수 있도록 bash 스크립트에서 공백을 사용하는 일반적인 논리를 이해하고 싶습니다.

몇 가지 예: 강제 [ $i == b ], 반대var1="foo"

답변1

하지만 Bash 스크립트에서 공백을 사용하는 일반적인 논리를 이해하고 싶습니다.

명령 인수 및 명령을 구분할 때 공백을 사용해야 합니다.핵심 단어(또는 소스에 따라 예약어). 이들은 {,,,,,,,, 등 입니다.​​​}!iffordodone

주변 공백은 필수가 아닙니다.운영자. 이는 최소한 명령문 종결자 ;&; 모든 재지정 연산자 &&와 괄호 및 입니다 . 리디렉션 연산자 앞의 선택적 파일 설명자 번호는 공백으로 구분할 수 없지만 연산자 주위의 추가 공백은 일반적으로 중요하지 않습니다.||><<()

따라서 다음은 모두 좋습니다.

true;true
cat<<file
true&&false
tac|rev
f()(echo foo)

이것들은 다음이 아닙니다:

if !somecmd; then ...
f(){echo foo}

첫 번째는 명령을 !somecmd실행하는 대신 명령을 찾아 somecmd종료 상태를 반전시킵니다. 두 번째 것은 키워드 '{'와 '{'가 }별도의 단어여야 하고 명령 시작 부분에서만 인식되기 때문에 작동하지 않습니다. f(){ echo foo;}예를 들어

if코스를 명령문 으로 사용할 수 없는 경우 단어 시작 부분부터 선택하면 if호출된 프로그램을 사용하기가 어렵습니다.ifconfig

ifsomecmd;then ...

(Fortran에 익숙하지 않다면 이는 분명할 수 있습니다.)

그렇다면 이것이 (연산자가 {아니라 연산자인지 어떻게 알 수 있습니까? 암기 학습으로 학습합니다. 이러한 차이는 많은 경우와 마찬가지로 역사적인 이유 때문일 수 있습니다. 바라보다:POSIX Shell Grammar의 중괄호 명령 그룹에서 여는 중괄호 뒤에 공백이 필요한 이유는 무엇입니까?

해당 질문에 대한 답변에는 참조와 함께 연산자 및 키워드에 대한 더 많은 논의가 있으므로 읽어보십시오.


하지만 위의 어느 것도 과제와 시험 foo=bar의 차이를 구분하는 데 실제로 도움이 되지는 않습니다 [ "$foo" = bar ].

여기서 핵심은 [일반 명령과 마찬가지로 연산자와 피연산자를 다른 인수로 사용하고 실제로 내부를 살펴보지 않는다는 것입니다. ls -l /somedirectory인수( -l/somedirectory) 를 구분하기 위해 공백이 필요한 것과 마찬가지로 에서도 마찬가지입니다 [.이 괄호 쌍은 쉘 구문의 일부가 아닙니다(또는 구문) 및 is not 은 =대부분의 실제 프로그래밍 언어의 해당 구문과 다릅니다.

미션의 경우 조금 까다롭습니다. 할당은 명령줄에 단독으로 나타날 필요가 없으며(명령과 함께 사용할 수 있음) 한 줄에 여러 할당이 있을 수 있습니다. 이와 같이:

$ foobar=123 foofoo=456 env|grep foo
foofoo=456
foobar=123

대략적으로 작동하는 방식은 쉘이 명령을 단어(위의 단어는 foobar=123, foofoo=456env)로 분할하고 초기 단어를 살펴서 할당처럼 보이는지 확인하는 것입니다. 둘 다 그렇지만 여기에는 할당이 없고 일반 매개변수만 있습니다 echo.

$ echo foo=bar
foo=bar

이 점에서 쉘 구문이 다를 수 있다고 생각하지만 두 개의 할당이 있고 인수가 없는 명령이 있는 경우 다음과 같은 것을 지원하면 이상하게 보일 수 있습니다(물론 Lua에 익숙하지 않은 경우).

foobar = 123 foofoo = 456 env

답변2

핵심은 공백으로 구분하는 것입니다.성격, 인용되지 않은 한, 그리고성격고려해야 할 사항:

기본적으로 쉘은 다음을 수행합니다.

  1. 입력 내용을 읽으십시오 [...]
  2. 다음에 설명된 인용 규칙에 따라 입력을 단어와 연산자로 나눕니다.인용하다. 이러한 태그는 메타 문자로 구분됩니다. [...]
  3. 태그를 단순 명령과 복합 명령으로 구문 분석합니다(참조:쉘 명령).

-3.1.1 쉘 동작

그리고:

간단한 명령은 가장 일반적으로 사용되는 명령입니다. 이는 단순히 공백으로 구분된 일련의 단어이며 쉘의 제어 연산자 [.] 중 하나로 종료됩니다.3.2.1 간단한 명령

그리고:

  1. 파서가 변수 할당(명령 이름 앞의 단어) 및 리디렉션으로 표시한 단어는 나중에 처리할 수 있도록 저장됩니다.
  2. 변수 할당이나 리디렉션이 아닌 단어는 확장됩니다 [...]. 확장 후 남은 단어가 있는 경우 첫 번째 단어는 명령 이름으로 처리되고 나머지 단어는 인수로 처리됩니다.

-3.7.1 간단한 명령 확장

"변수에 할당하기 위해 표시된 단어 [...]"라고 말하는 방법에 유의하십시오. 따라서 변수 할당은 단일 단어여야 하므로 다음은 다음과 같습니다.오직변수 할당:

  • var=value
  • var=" value"

다음의 경우에는 그렇지 않습니다.

  • var= value✗ (두 단어: 변수 할당 var=- 빈 문자열에 할당 - 명령용 value)
  • var =value✗ (두 단어: var매개변수가 있는 명령 =value)
  • var" =value"✗ (한 단어: 단, 변수 이름은 인용할 수 없으므로 명명된 명령입니다 var =value.)
  • "var=value"✗ (한 단어: 단, 변수 이름은 인용할 수 없으므로 명명된 명령입니다 var=value.)

이제 for 는 [ var = value ]테스트 를 기대하는 [명령( 과 동일한 명령 test)이고 테스트의 피연산자는 다음과 같습니다.별도의 주장. 이렇게 하면 예를 들어 [ "$var" = "$value" ]or where 와 같은 작업을 수행할 수 있고 테스트처럼 보이지만 각각이 단일 인수이기 때문에 그렇지 않은 것을 포함할 수 있습니다.test "$var" = "$value"var="a = b"value="b = c"

매개변수는 별도의 단어여야 하므로 주변에 공백이 필요합니다 =. 이것이 "$var"바로 "$value"인용되어야 하는 이유이기도 합니다. 그렇지 않으면 쉘이 이를 별도의 단어로 나누어 [실패하게 됩니다.

관련 정보