나는 이 사이트에서 웹 검색과 검색을 시도했지만 bash의 문자열에 공백을 사용하는 것과 관련된 문제만 발견했습니다. 그러나 올바른 사용법(필수 사항과 그 반대)을 더 잘 기억할 수 있도록 bash 스크립트에서 공백을 사용하는 일반적인 논리를 이해하고 싶습니다.
몇 가지 예: 강제 [ $i == b ]
, 반대var1="foo"
답변1
하지만 Bash 스크립트에서 공백을 사용하는 일반적인 논리를 이해하고 싶습니다.
명령 인수 및 명령을 구분할 때 공백을 사용해야 합니다.핵심 단어(또는 소스에 따라 예약어). 이들은 {
,,,,,,,, 등 입니다.}
!
if
for
do
done
주변 공백은 필수가 아닙니다.운영자. 이는 최소한 명령문 종결자 ;
및 &
; 모든 재지정 연산자 &&
와 괄호 및 입니다 . 리디렉션 연산자 앞의 선택적 파일 설명자 번호는 공백으로 구분할 수 없지만 연산자 주위의 추가 공백은 일반적으로 중요하지 않습니다.||
>
<<
(
)
따라서 다음은 모두 좋습니다.
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=456
및 env
)로 분할하고 초기 단어를 살펴서 할당처럼 보이는지 확인하는 것입니다. 둘 다 그렇지만 여기에는 할당이 없고 일반 매개변수만 있습니다 echo
.
$ echo foo=bar
foo=bar
이 점에서 쉘 구문이 다를 수 있다고 생각하지만 두 개의 할당이 있고 인수가 없는 명령이 있는 경우 다음과 같은 것을 지원하면 이상하게 보일 수 있습니다(물론 Lua에 익숙하지 않은 경우).
foobar = 123 foofoo = 456 env
답변2
핵심은 공백으로 구분하는 것입니다.성격, 인용되지 않은 한, 그리고성격고려해야 할 사항:
기본적으로 쉘은 다음을 수행합니다.
그리고:
간단한 명령은 가장 일반적으로 사용되는 명령입니다. 이는 단순히 공백으로 구분된 일련의 단어이며 쉘의 제어 연산자 [.] 중 하나로 종료됩니다.3.2.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"
인용되어야 하는 이유이기도 합니다. 그렇지 않으면 쉘이 이를 별도의 단어로 나누어 [
실패하게 됩니다.