다음 명령과 마찬가지로,
if true; then
IFS=":" read a b c d e f <<< "$test"
책에는 할당 명령( IFS ":"
)이 주 명령( ) 앞에 사용 되면 read a b c d e f <<< "$value"
그 값이 일시적으로 주 명령에 유효하다고 나와 있습니다. 따라서 read
명령은 구분 기호를 사용합니다 :
.
하지만 이 명령처럼
if true; then
HOME="hello" echo "$HOME"
에코 메시지는 hello가 아닙니다. 위 명령은 실제로 무엇을 의미합니까?
답변1
평가가 어떻게 이루어지느냐의 문제로 귀결됩니다. 두 예제 모두 동일한 방식으로 작동하지만 셸(여기서는 bash)이 변수를 확장하는 방식으로 인해 문제가 발생합니다.
이 명령을 작성할 때:
HOME="foo" echo $HOME
$HOME
확장명령이 실행되기 전에. 따라서 명령에 대해 설정한 새 값이 아닌 원래 값으로 확장됩니다. 변수는 HOME
명령이 실행되는 환경에서 변경되지만 상위 변수에서 변수를 인쇄합니다.echo
$HOME
이를 설명하기 위해 다음 상황을 고려하십시오.
$ HOME="foo" bash -c 'echo $HOME'
foo
$ echo $HOME
/home/terdon
위에서 볼 수 있듯이 첫 번째 명령은 일시적으로 변경된 값을 인쇄하고 HOME
두 번째 명령은 원래 값을 인쇄하여 변수가 일시적으로만 변경되었음을 나타냅니다. 명령이 큰따옴표( ) 대신 작은따옴표( )로 묶여 있기 때문에 bash -c ...
변수는 확장되지 않고 변경되지 않은 채 새 bash 프로세스에 전달됩니다. 그런 다음 이 새로운 프로세스는 이를 확장하고 설정된 새 값을 인쇄합니다. 다음 명령을 사용하면 이런 일이 발생하는 것을 볼 수 있습니다.' '
" "
set -x
$ set -x
$ HOME="hello" echo "$HOME"
+ HOME=hello
+ echo /home/terdon
/home/terdon
위에서 볼 수 있듯이,바꾸다 $HOME
으로 전달되지 않습니다 echo
. 확장자 값만 볼 수 있습니다. 비교:
$ HOME="hello" bash -c 'echo $HOME'
+ HOME=hello
+ bash -c 'echo $HOME'
hello
여기서는 작은따옴표로 인해 변수가 해당 값 대신 새 프로세스에 전달됩니다.
답변2
쉘이 행을 구문 분석할 때 해당 행을 단어로 표시합니다.다양한 확장 실행(순서대로) 단어를 입력한 다음 명령을 실행합니다.
생각하다test=1:2:3:4:5:6
이 명령을 살펴보겠습니다. IFS=":" read a b c d e f <<< "$test"
토큰화 후,매개변수 확장발생하다:IFS=":"
read
a
b
c
d
e
f
<<<
"1:2:3:4:5:6"
쉘은 읽기 명령 중에 IFS 변수를 설정하고read
$IFS를 입력에 적용하는 방법을 알아보세요.을 클릭하고 변수 이름에 값을 할당합니다.
이 명령은 비슷한 내용을 가지고 있지만 결과는 다릅니다.HOME="hello" echo "$HOME"
매개변수 확장이 발생하므로앞으로명령 시작 부분에 셸에는 다음이 포함됩니다.
HOME="hello" echo "/home/username"
그러면 echo 명령을 실행하는 동안 $HOME의 새 값이 전혀 사용되지 않습니다.
하고 싶은 일을 이루려면 다음 중 하나를 선택하세요.
# Delay expansion of the variable until its new value is set
HOME="hello" eval 'echo "$HOME"'
또는
# Using a subshell, so the altered env variable does not affect the parent.
# The semicolon means that the variable assignment will occur before
# the variable expansion
(HOME="hello"; echo "$HOME")
그러나 첫 번째 것을 선택하지 마십시오.
답변3
범위에는 환경 변수와 지역 변수라는 두 가지가 있습니다. 환경 변수는 모든 프로세스에 대해 유효한 반면(참고자료 참조 setenv
) getenv
, 로컬 변수는 해당 셸 세션 내에서만 유효합니다. (눈에 띄는 차이는 아닙니다...)
환경 수정은 로컬 환경을 사용하는 동안 암시적으로 env
(귀하의 예에서와 같이) 수행 되므로 아무런 효과가 없습니다.echo ...
env
지역 변수를 수정하려면 다음을 사용하십시오.
( HOME="foo" ; echo "$HOME" )
여기서 괄호는 할당 범위를 정의합니다.