그 범위는 프로세스에 따라 구분됩니다.

그 범위는 프로세스에 따라 구분됩니다.

방금 쉘 변수의 범위에 대해 불분명하다는 문제가 발생했습니다.

나는 작업을 수행하기 bundle install위해 값을 사용하는 Ruby 명령인 this 을 사용하려고 합니다 . $GEM_HOME이 값을 설정했지만 그림과 같이 $GEM_HOME명령은 값을 사용할 때까지 해당 값을 무시합니다 .exportexport GEM_HOME=/some/path

나는 이것이 어떤 방식으로든 변수를 "전역"으로 만든다는 것을 읽었습니다.환경 변수) 그런데 그게 무슨 뜻인지 이해가 안 돼요. 프로그래밍의 전역 변수에 대해서는 이해하지만 다른 프로그램의 전역 변수에 대해서는 이해하지 못합니다.

또한 내가 설정한 변수가 현재 쉘 세션에만 적용된다는 점을 감안할 때 데몬 등에 대해 어떻게 설정합니까?

쉘 변수는 어떤 범위를 가질 수 있습니까?

답변1

프로세스는 트리로 구성됩니다. 각 프로세스에는 고유한 상위 프로세스가 있습니다. 그렇지 않으면 init항상 PID1이고 상위 프로세스가 없습니다.

새로운 프로세스를 생성하려면 일반적으로 한 쌍의 fork/ execv시스템 호출이 필요하며, 여기서 하위 프로세스의 환경은 다음과 같습니다.복사부모 프로세스의.

쉘의 변수를 환경에 넣으려면 export모든 하위 항목이 재귀적으로 볼 수 있도록 변수를 사용해야 합니다. 그러나 하위 프로세스가 변수 값을 변경하는 경우 변경된 값은 하위 프로세스와 해당 하위 프로세스가 생성하는 모든 프로세스에만 표시됩니다.뒤쪽에변경 사항(복사, 상술 한 바와 같이).

또한 하위 프로세스가 환경을 변경할 수 있으며 예를 들어 기본값으로 재설정될 수 있다는 점을 고려하세요 login.

답변2

최소한 ksh및 아래에 bash변수가 있을 수 있습니다.범위, 아니지금까지 남은 모든 답변과 같습니다.

내보낸(즉, 환경) 변수와 셸에서 내보내지 않은 변수의 범위 외에도 함수 로컬 변수에 대한 세 번째 더 좁은 범위가 있습니다.

쉘 함수에서 마커를 사용하여 선언된 변수는 typeset해당 변수가 선언된 함수와 거기에서 호출되는 (하위) 함수 내에서만 볼 수 있습니다.

ksh/ bash코드:

# Create a shell script named /tmp/show that displays the scoped variables values.    
echo 'echo [$environment] [$shell] [$local]' > /tmp/show
chmod +x /tmp/show

# Function local variable declaration
function f
{
    typeset local=three
    echo "in function":
    . /tmp/show 
}

# Global variable declaration
export environment=one

# Unexported (i.e. local) variable declaration
shell=two

# Call the function that creates a function local variable and
# display all three variable values from inside the function
f

# Display the three values from outside the function
echo "in shell":
. /tmp/show 

# Display the same values from a subshell
echo "in subshell":
/tmp/show

# Display the same values from a disconnected shell (simulated here by a clean environment start)
echo "in other shell"
env -i /tmp/show 

다음 출력을 생성합니다.

in function:
[one] [two] [three]
in shell:
[one] [two] []
in subshell:
[one] [] []
in other shell
[] [] []

보시다시피, 내보낸 변수는 처음 세 위치에서 나타나고, 내보내지 않은 변수는 현재 셸 외부에 나타나지 않으며, 함수 로컬 변수는 함수 자체 외부에는 값이 없습니다. 마지막 테스트에서는 값이 전혀 표시되지 않습니다. 이는 내보낸 변수가 쉘 간에 공유되지 않기 때문입니다. 즉, 상속만 가능하고 상속된 값은 나중에 상위 쉘의 영향을 받지 않습니다.

후자의 동작은 완전히 전역적이고 모든 프로세스에서 공유되는 시스템 변수를 사용할 수 있는 Windows의 동작과 완전히 다릅니다.

답변3

그 범위는 프로세스에 따라 구분됩니다.

다른 응답자들은 쉘 변수 범위가 대략적이라는 것을 이해하는 데 도움을 주었습니다.프로세스와 그 하위 항목.

ls명령줄에 명령을 입력하면 실제로 ls프로그램을 실행하기 위해 프로세스가 분기됩니다. 새 프로세스에는 쉘이 상위 프로세스로 포함됩니다.

모든 프로세스에는 하위 프로세스로 전달되지 않는 자체 "로컬" 변수가 있을 수 있습니다. 또한 "환경" 변수를 설정할 수도 있습니다. 를 사용하여 export환경 변수를 만듭니다 .두 경우 모두, 관련되지 않은 프로세스(원래 프로세스의 형제)는 변수를 보지 못합니다. 우리는 단순히 자식 프로세스가 보는 것을 제어합니다.

bash 쉘이 있다고 가정하고 이를 A라고 부르겠습니다. 를 입력하면 bash하위 프로세스 bash 쉘이 생성됩니다. 이를 B라고 부르겠습니다. A에서 호출 하는 모든 항목은 export여전히 ​​B에 설정됩니다.

이제 B에서는 FOO=b. 다음 두 가지 중 하나가 발생합니다.

  • B가 (A로부터)라는 환경 변수를 받지 못하면 FOO지역 변수를 만듭니다. B의 아이들은 그것을 얻지 못할 것입니다(B가 전화하지 않는 한 export).
  • B라면했다(A로부터)라는 이름의 환경 변수를 FOO받습니다 .자신과 이후에 분기된 하위 항목을 수정합니다.. B의 자녀는 B가 할당한 값을 보게 됩니다. 하지만,이는 A에 전혀 영향을 미치지 않습니다.

다음은 간단한 데모입니다.

FOO=a      # set "local" environment variable
echo $FOO  # 'a'
bash       # forks a child process for the new shell
echo $FOO  # not set
exit       # return to original shell
echo $FOO  # still 'a'

export FOO # make FOO an environment variable
bash       # fork a new "child" shell
echo $FOO  # outputs 'a'
FOO=b      # modifies environment (not local) variable
bash       # fork "grandchild" shell
echo $FOO  # outputs 'b'
exit       # back to child shell
exit       # back to original shell
echo $FOO  # outputs 'a'

이 모든 것이 내 원래 문제를 설명합니다. GEM_HOME셸에서 설정했지만 호출하면 bundle install하위 프로세스가 생성됩니다. 내가 그것을 사용하지 않았기 때문에 export자식 프로세스는 쉘을 받지 못했습니다 GEM_HOME.

내보내기 취소

"unexport"를 사용하면 변수가 자식에게 전달되는 것을 방지할 수 있습니다 export -n FOO.

export FOO=a   # Set environment variable
bash           # fork a shell
echo $FOO      # outputs 'a'
export -n FOO  # remove environment var for children
bash           # fork a shell
echo $FOO      # Not set
exit           # back up a level
echo $FOO      # outputs 'a' - still a local variable

답변4

내보내기에 대해 내가 찾을 수 있는 가장 좋은 설명은 다음과 같습니다.

http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_02.html

서브쉘 또는 서브쉘에 설정된 변수는 해당 서브쉘이 정의된 서브쉘에만 표시됩니다. 내보낸 변수는 실제로 환경 변수입니다. 따라서 명확하게 말하면 자신의 쉘을 실행하면 bundle install변수로 설정되지 않는 한(내보내기라고도 함) 쉘이 표시되지 않습니다.$GEM_HOMEenvironment

여기에서 변수 범위에 대한 문서를 볼 수 있습니다.

http://www.tldp.org/LDP/abs/html/subshells.html

관련 정보