다음과 같은 변수를 내보내는 스크립트가 있다고 가정해 보겠습니다.
#!/bin/bash
foo(){
eval export one=1
}
foo1(){
eval export two=2
}
(foo)
foo1
echo "one=$one"
echo "two=$two"
그러나 나는 다음과 같은 결과를 얻습니다.
root@centos1:~>/tmp/test.sh
one=
two=2
값을 볼 수 없지만 $one
볼 수 있는 이유는 무엇일까요 $two
?
답변1
전역 변수설정된 순간부터 설정이 해제되거나 프로세스가 종료되는 순간까지 지속됩니다. 전역(또는 로컬) 변수는 관련되지 않은 하위 프로세스에 의해 상속되지 않습니다(하위 프로세스가 포크(서브쉘)인 경우 내보냈거나 내보내지 않은 모든 것의 복사본을 얻습니다).
글로벌 수출 변수전역 변수와 유사하지만 하위 프로세스(관련되지 않은 하위 프로세스도 포함)에 의해 자동으로 상속됩니다(프로세스 환경의 일부로). (내보내기를 사용하면 CXXFLAGS
와 같은 프로세스에 와 같은 변수를 전달할 수 있습니다 make
. 이는 확실히 셸의 하위 셸이 아니며 make
생성된 모든 프로세스도 해당 변수를 가져옵니다.)
귀하의 예에서는 ()
모든 것의 복사본을 얻는 하위 쉘을 만듭니다. 이 foo
명령은 내보낸 변수를 추가하여 서브셸을 수정한 다음 내보낸 변수를 사용하지 않고 서브셸을 종료합니다(손자 없음). 이제 하위 프로세스에서 상위 프로세스로 암시적으로 정보가 전송되지 않습니다. 아이들이 자신의 환경에서 하는 일은 부모에게 영향을 미치지 않습니다. 이것이 변수가 one
설정되지 않은 이유입니다.
그건 그렇고, 이 경우에는 eval
필요하지 않습니다 .eval
답변2
명령을 묶으면 ( )
해당 명령이 하위 쉘에 있게 됩니다.
이는 파이프나 종료를 원할 경우 유용할 수 있습니다.
예를 들어, 다음 명령은
( date ; cmd1 ; cmd2 ) | grep ...
처음 3개의 명령이 연결되어 출력을 grep
.
이를 { }
위해서는 bash의 매뉴얼 페이지(bash(1)
); 이것은 발췌입니다:
(list)
list
서브셸 환경에서 실행됩니다(참조:명령 실행 환경 다음과 같은). 쉘 환경에 영향을 미치는 변수 할당 및 내장 명령은 명령이 완료된 후에 더 이상 유효하지 않습니다. 반환 상태는 종료 상태입니다.list
.
{ list; }
list
현재 쉘 환경에서 실행하면 됩니다.list
개행 또는 세미콜론으로 종료되어야 합니다. 이것은 ... 불리운다그룹 명령. 반환 상태는 종료 상태입니다.list
. 메타 문자와는 달리(
그리고)
,{
그리고}
예예약어그리고 반드시 발생해야 하는 예약어 인정받을 수 있도록 하세요. 단어 분리를 유발하지 않으므로 다음과 결합해야 합니다.list
공백이나 기타 셸 메타 문자를 전달합니다.
당신은 또한 볼 수 있습니다쉘의 제어 및 리디렉션 연산자는 무엇입니까?