AFAIK는 스크립트 실행 cat
과 마찬가지로 실행 시 새 프로세스를 포크하는 외부 명령입니다 . 그렇지만 다른 외부 명령에서 사용되는 명령 환경을 사용하고 sh -c
싶습니다 .cat
f=test.txt sh -c 'cat "$f"'
파일의 내용을 표시하면 안되나요?
f=test.txt cat $f
?
참고: 가 무엇인지 묻는 것이 아닙니다 someVariable=someValue command
. 왜 첫 번째 예에서는 명령 변수를 사용하고 두 번째 예에서는 사용하지 않는지 묻고 있습니다. 두 번째 예에서 변수 확장이 발생하는 방식은 첫 번째 예에서도 발생해야 합니다.
답변1
일반화하다
작은따옴표 명령 매개변수를 확장하기 전에 f=test.txt sh -c 'cat "$f"'
변수 할당이 발생하므로 이 명령은 출력을 생성합니다 . 작은따옴표는 하위 명령이 실행되기 전에 확장이 발생하는 것을 방지합니다.f=test.txt
'cat "$f"'
cat "$f"
이 명령 f=test.txt cat $f
은아니요f=test.txt
변수 할당이 발생하기 때문에 출력을 생성합니다.뒤쪽에(따옴표 없음) 명령 매개변수 확장 $f
.
왜 f=test.txt cat $f
출력이 생성되지 않습니까?
f=test.txt cat $f
먼저, 예상한 대로 이 명령이 출력을 생성하지 않는 이유를 설명하겠습니다 . 여기서 평가 순서에 대해 약간의 혼란이 있을 수 있습니다.간단한 명령.
f=test.txt
명령 본문의 변수 확장(예: $f
in 확장 ) cat $f
이전에 명령 프롤로그의 변수 할당(예: 할당)이 발생한다고 가정할 수 있습니다 . 그러나 그것은 진실이 아니다. 이를 확인하려면 페이지를 참조하세요.간단한 명령 확장Bash 매뉴얼에서 또는간단한 명령에 대한 섹션내부에POSIX 사양. 두 참조 모두 다음 단락을 포함합니다.
"간단한 명령"은 임의의 순서로 선택적인 변수 할당 및 리디렉션의 시퀀스이며 선택적으로 단어와 리디렉션이 뒤따르고 제어 연산자에 의해 종료됩니다.
주어진 간단한 명령을 실행해야 하는 경우(즉, AND-OR 목록이나사례명령문은 간단한 명령을 우회하지 않습니다.) 명령 텍스트의 처음부터 끝까지 다음 확장, 할당 및 리디렉션을 수행해야 합니다.
2단계에서는 명령에서 변수 확장이 발생하지만 1단계에서는 변수 할당이 3단계와 4단계에 저장된다는 점에 유의하세요. 따라서 표현식은 할당이 발생하기 전 cat $f
(인수 없이)으로 확장됩니다 . 이는 출력이 나오지 않는 이유를 설명합니다.cat
f=test.txt
이 주제에 대한 자세한 내용은 다음 게시물을 참조하세요.
왜f=test.txt sh -c 'cat "$f"'
하다산출물을 생산하다
다음으로 명령이 왜 필요한지 설명하겠습니다.f=test.txt sh -c 'cat "$f"'
하다출력을 생성합니다. 이를 위해 우리는 살펴보아야 합니다.쉘에서 수행되는 일반적인 작업의 전체 목록:
쉘은 파일에서 입력을 읽습니다(참조:쉿), -c 옵션 또는체계()그리고팝펜()POSIX.1-2008 시스템 인터페이스 볼륨에 정의된 기능입니다. 셸 명령 파일의 첫 번째 줄이 "#!" 문자로 시작하면 결과가 지정되지 않습니다.
쉘은 입력을 토큰으로 나눕니다. 단어와 연산자를 참조하세요.토큰 인식.
쉘은 각 명령의 여러 부분에 대해 (별도로) 다양한 확장을 수행하여 명령 및 인수로 처리되는 경로 이름 및 필드 목록을 생성합니다.단어 표현.
쉘은 리디렉션을 수행합니다(참조리디렉션) 인수 목록에서 리디렉션 연산자와 해당 피연산자를 제거합니다.
쉘은 함수를 실행합니다(참조:기능 정의 명령), 내장(참조특수 내장 유틸리티), 실행 파일 또는 스크립트(매개변수 이름을 1부터 n까지의 위치 인수로 지정하고 명령 이름(또는 스크립트 내의 함수의 경우 스크립트 이름을 지정)을 0의 위치 인수로 지정합니다(참조).명령어 검색 및 실행).
쉘은 선택적으로 명령이 완료될 때까지 기다리고 종료 상태를 수집합니다(참조:명령의 종료 상태).
여기에서 함수/내장/실행 가능/스크립트 호출을 볼 수 있습니다(이 목록의 6단계).뒤쪽에간단한 명령을 구문 분석합니다. 그래서 f=test.txt
할당이 발생합니다앞으로프로그램 실행 sh -c 'cat "$f"'
. 매개변수는 작은따옴표로 묶여 있으므로 구문 분석만 수행됩니다.뒤쪽에명령이 실행됩니다. 따라서 하위 명령은 cat "test.txt"
.
답변2
쉘 명령에 대한 변수 할당은 명령에 전달된 환경에만 영향을 미치며 쉘이 실행되는 환경에는 영향을 미치지 않습니다.
좀 더 직접적으로 보실 수 있어요
$ f=1
$ f=2 echo $f
1
$
로 설정된 환경에서 실행되지만 echo
명령을 빌드하는 데 사용되는 셸 환경이 아닌 명령 환경(빌드 중인)에서 실행되도록 할당됩니다.f
2
명령이 없는 할당만 실행 중인 셸 환경에 영향을 미치며, 셸 환경은 명령을 구성하는 데 사용됩니다.
답변3
두 번째 예에서는 $f
가 아닌 셸에 의해 확장되기 때문에 셸 환경에 다른 설정이 없다고 cat
가정하고 빈 문자열로 확장한 다음 아무것도 없는 것처럼 stdin에서 읽습니다. 주어진 매개변수는 동일합니다.f
$f
cat
첫 번째 예에서는 $f
작은따옴표 안에 있으므로 원래 쉘로 확장되지는 않지만예인스턴스 확장을 통해 sh
확인cat "$f"
그리고f
해당 환경에 설정 되었습니다 .