쉘 명령 대체 차이점/예외

쉘 명령 대체 차이점/예외

Bash에서 스크립트를 작성할 때 다음 구조를 사용하여 명령 출력에 변수를 할당하는 방법을 배웠습니다.

variable=$(command-string)

이를 명령 대체라고 하며 하위 쉘 환경에서 명령 문자열의 내용을 실행합니다.

뭔가 특이한 점을 발견했을 수도 있습니다.

이러한 형태의 명령 대체를 수행할 때 변수 할당이 없으면 결과가 달라집니다.

예:

cmd=date
var=$(echo $cmd)
echo $var
$(echo $cmd)

산출:

date
Fri Jun 29 15:11:58 EDT 2018

변수 할당이 없는 명령 대체는 명령 실행의 표준 출력을 평가하려는 것처럼 보이지만 변수 할당은 그렇지 않습니다.

답변1

명령 대체는 다음과 같이 평가됩니다.date

아무것도 할당하지 않았으므로 기본적으로 date명령 프롬프트에 입력만 하면 됩니다.

$ set -x
$ cmd=date
+ cmd=date
$ var=$(echo $cmd)
++ echo date
+ var=date
$ echo $var
+ echo date
date
$ $(echo $cmd)
++ echo date
+ date
Fri Jun 29 13:26:55 MDT 2018

date유효한 명령이므로 예상대로 실행됩니다 .

답변2

나는 합리적이고 다소 간결한 기술적 설명을 생각해냈다고 믿습니다. 우리는 CLI(Command Line Interpreter)를 다루고 있으며, 파서가 대체 표시 "$("를 만났을 때의 해석 단계에 따라 명령 대체 결과가 달라집니다.

cmd="date"

단순 할당; 변수 "cmd"에는 문자열 "date"가 있습니다.

var=$(echo $cmd)
$(echo $cmd)

첫 번째 경우, 파서(왼쪽에서 오른쪽으로 읽음)는 토큰 "="을 발견하므로 변수 할당에 해당하는 문자열을 기다리고 있음을 알게 됩니다. 두 번째 경우, 파서가 "$("에 도달하면 파서는 처리 중인 명령 유형을 아직 결정하지 못했습니다. 두 경우 모두 파싱이 일시 중지되고 하위 쉘 환경이 생성됩니다. 대괄호 사이의 문자열 stdout의 내용은 다음과 같습니다. 따옴표가 없는 해당 닫는 대괄호인 "$("와 그 사이의 모든 항목을 대체하기 위해 CLI에 의해 해석됩니다. 이제 CLI는 중단된 부분부터 계속됩니다. 이 예에서 이 두 인스턴스 사이에 stdout에는 둘 다 문자열 "date"가 포함되어 있습니다. 첫 번째 경우 CLI는 동등한 문자열을 예상하므로 "var=date"를 문자열 "date"를 변수 "var"에 할당하는 것으로 해석합니다. 이 경우 CLI는 "date"를 현재 프로그램에서 유효한 프로그램으로 해석합니다. 따라서 실제로는 아무런 문제가 없습니다. 이는 단지 인터프리터가 대체를 수행하는 방식일 뿐입니다.

관련 정보