명령의 bash 스크립트 임시 값

명령의 bash 스크립트 임시 값

다음 명령과 마찬가지로,

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" )

여기서 괄호는 할당 범위를 정의합니다.

관련 정보