2017-09-04 18 views
1

현재 프로젝트에서 실행 중에 실행되는 루프를 실행하여 나중에 필요한 변수를 정의합니다. 티를 사용하여 로깅을 추가하기 전까지는 모든 것이 잘 수행되었으므로 나중에 로그에서 파일을 검사 할 수 있습니다. stdout과 stderr를 모두 기록하려면 |& (바로 가기는 2>&1 |)을 적용했습니다. 그러나 이상하게도 변수의 값은 손실됩니다.배쉬 : 로깅 영향 변수 범위?

for i in 1 2 3 ; do 
    # ... do something meaningful ... 
    myVar=test1 
done |& tee test1 
echo "myVar=$myVar" 

출력 :

myVar= 

한편 내가 더 잘 작동하는 방법을 발견 : 나는 파일 리디렉션프로세스 대체, 변수 정의 작품의 조합으로 전환합니다.

for i in 1 2 3 ; do 
    # ... do something meaningful ... 
    myVar=test2 
done > >(tee test2 ) \ 
    2> >(tee test2 >&2) 
echo "myVar=$myVar" 

출력 : :-)

  1. 왜 값이 첫 번째 예에서 길을 잃지 않는 이유를 이해 할

    myVar=foo 
    

    그러나?

  2. 두 번째로 길을 잃지 않는 이유는 무엇입니까?

알려주시겠습니까?

+1

은 파이프의 양쪽 서브 쉘을 생성한다. 티와 아무런 관련이 없습니다. 어떤 명령으로 시도해보십시오. 두 번째 방법은'>()'에 대한 서브 쉘을 생성하기 만하면 거기에없는 것이 손실되지 않습니다. – 123

답변

1

As 123 said 파이프가 하위 셸 (새 범위)을 만들고 하위 셸이 상위 셸의 변수에 액세스하지 못합니다.

다음 도우미 함수는 쉘의 PID와 변수 a의 값을 표시합니다.

show_a() { echo $BASHPID: a=$a >&2; } 

다음 예에서는 리디렉션 만 사용되기 때문에 하위 셸을 만들지 않습니다. 하나의 변수 a 만 사용됩니다.

$ a=1; show_a; { a=2; show_a; } > /dev/null ; show_a 
31072: a=1 
31072: a=2 
31072: a=2 

그러나이 예에서는 파이프 때문에 하위 셸을 만듭니다. 각 프로세스에는 자체 변수 a이 있습니다. 이 양단 근접 내부 환경을 상실 할 때 배관을 사용한

$ a=1; show_a; { a=2; show_a; } | tee ; show_a 
31072: a=1 
6375: a=2 
31072: a=1 
+0

알았습니다! 둘 다 고마워. 실행 중에 $ BASHPID를 출력하는 좋은 트릭. – Hardy