source

내보내기 여부와 관계없이 변수 정의

factcode 2023. 4. 9. 22:26
반응형

내보내기 여부와 관계없이 변수 정의

죠?export

다음 중 어떤 차이가 있습니까?

export name=value

그리고.

name=value

export는 변수를 서브태그에 사용할 수 있도록 합니다.

그것은,

export name=value

는 해당 셸 프로세스에서 실행하는 프로세스에서 변수 이름을 사용할 수 있음을 의미합니다.공정에서 이 변수를 사용하려면export및 그 셸에서 프로세스를 실행합니다.

name=value

는 변수 범위가 셸로 제한되어 다른 프로세스에서는 사용할 수 없음을 의미합니다.루프 변수, 임시 변수 등에 사용합니다.

변수를 내보내면 상위 프로세스가 변수를 사용할 수 없습니다.즉, 생성된 프로세스에서 변수를 지정 및 내보내면 변수를 시작한 프로세스에서 변수를 사용할 수 없습니다.

다른 답변이 무엇을 의미하는지 설명하려면:

$ foo="Hello, World"
$ echo $foo
Hello, World
$ bar="Goodbye"
$ export foo
$ bash
bash-3.2$ echo $foo
Hello, World
bash-3.2$ echo $bar

bash-3.2$ 

서브셸을 산란할 때 반드시 bash로 수출할 필요는 없다고 하는 견해도 있고, 그 반대의 견해도 있다.서브셸)의(서브셸(서브셸)에해 주세요.(),``,$() 루프)및 리터럴 「」)bash스크립트에 표시됩니다).

  • 서브셸은 내보낸 상태에 관계없이 부모로부터 모든 변수에 액세스할 수 있습니다.
  • 하위 프로세스에는 내보낸 변수만 표시됩니다.

이들 2개의 구조에서 공통되는 것은 둘 다 변수를 부모 셸로 되돌릴 수 없다는 것입니다.

$ noexport=noexport; export export=export; (echo subshell: $noexport $export; subshell=subshell); bash -c 'echo subprocess: $noexport $export; subprocess=subprocess'; echo parent: $subshell $subprocess
subshell: noexport export
subprocess: export
parent:

또 다른 혼란의 원인이 있는데, 일부에서는 '포킹된' 하위 프로세스가 내보내기되지 않은 변수를 인식하지 못한다고 생각합니다.보통 fork() 뒤에 exec()이 바로 오므로 fork()가 검색 대상인 것처럼 보이지만 실제로는 exec()입니다. fork()를하지 않고 fork를 사용하여 명령을 할 수 .exec명령어 및 이 메서드에 의해 시작된 프로세스도 보고되지 않은 변수에 액세스할 수 없습니다.

$ noexport=noexport; export export=export; exec bash -c 'echo execd process: $noexport $export; execd=execd'; echo parent: $execd
execd process: export

」는 되지 않는 해 주세요.parent:부모 이 ""로 에,exec명령어를 실행할 수 있는 것은 아무것도 없습니다.

답변은 틀렸지만 역사적 목적을 위해 남겨졌다.아래 두 번째 편집을 참조하십시오.

다른 사람들은 내보내기가 변수를 하위 쉘에서 사용할 수 있게 만든다고 대답했습니다. 이는 맞지만 부작용에 불과합니다. 해당 셸 즉, 셸 콜은 " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ."putenv(3) ★★★★★★★★★★★★★★★★★」setenv(3)를 참조해 주세요.
프로세스 환경은 exec 전체에서 상속되므로 변수가 하위 쉘에 표시됩니다.

편집 (5년간의 전망으로):이건 바보 같은 대답이야.'내보내기'의 목적은 변수들이 하위 셸이든 하위 프로세스이든 상관없이 "이후 실행되는 명령 환경"으로 만드는 것입니다.단순한 구현은 단순히 변수를 셸 환경에 배치하는 것이지만, 이는 구현을 불가능하게 만듭니다.export -p.

두 번째 편집(또 5년 후).이 대답은 그저 기이하다.한때 bash가 내보낸 변수를 자체 환경에 넣는다고 주장할 만한 이유가 있었을지도 모르지만, 이러한 이유는 여기에 기재되어 있지 않고, 현재는 역사로 남아 있지 않습니다.자세한 내용은 환경으로 함수 로컬 변수 내보내기를 참조하십시오.

export NAME=value하위 공정에 의미가 있는 설정 및 변수의 경우.

NAME=value현재 셸 프로세스 전용 임시 변수 또는 루프 변수의 경우.

것은, 을 참조해 주세요.export는 작성 시 서브프로세스와 그 서브프로세스에 복사되는 환경 내의 변수 이름을 나타냅니다.하위 프로세스에서 이름 또는 값은 복사되지 않습니다.

  • 일반적인 오류는 등호 주위에 공백을 두는 것입니다.

    $ export FOO = "bar"  
    bash: export: `=': not a valid identifier
    
  • 변수(「」)만B로 볼 수

    $ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B" | bash
    A is . B is Bob
    
  • 서브프로세스가 변경되어도 메인셸은 변경되지 않습니다.

    $ export B="Bob"; echo 'B="Banana"' | bash; echo $B
    Bob
    
  • 내보내기로 표시된 변수는 하위 프로세스를 만들 때 값이 복사됩니다.

    $ export B="Bob"; echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash &
    [1] 3306
    $ B="Banana"; echo '(sleep 30; echo "Subprocess 2 has B=$B")' | bash 
    Subprocess 1 has B=Bob
    Subprocess 2 has B=Banana
    [1]+  Done         echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash
    
  • ( 「 」 「 」 「 」 「 」 「 」 。man environ

     $ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB"
     BOB=Bob
    

그래서, 이제 여름의 태양처럼 맑아야 해요!브레인 애그뉴, 알렉스프, 그리고 윌리엄 프루셀 덕분이다.

변수를 내보내고 나중에 값을 변경할 수 있습니다.변수의 변경된 값은 하위 프로세스에서 사용할 수 있습니다.를 수행해야 .export -n <var>속성을 제거합니다.

$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset

export는 현재 셸에서 분기된 모든 셸에서 변수를 사용할 수 있도록 합니다.

이미 알고 계시겠지만 UNIX를 사용하면 프로세스에 키/값 쌍인 환경 변수 세트를 가질 수 있습니다. 키/값 쌍은 모두 문자열이 됩니다.운영체제는 각 프로세스별로 이들 쌍을 별도로 보관해야 합니다.

프로그램은 다음 UNIX API를 통해 환경 변수에 액세스할 수 있습니다.

  • char *getenv(const char *name);
  • int setenv(const char *name, const char *value, int override);
  • int unsetenv(const char *name);

프로세스는 상위 프로세스에서 환경 변수도 상속합니다.운영체제는 자녀 프로세스가 생성되는 시점에 모든 "envars"의 복사본을 만드는 역할을 합니다.

Bash는 다른 셸과 마찬가지로 사용자 요구에 따라 환경변수를 설정할 수 있습니다.이런 거export에 존재합니다.

exportBash Bash 입니다.이 명령어로 설정된 모든 변수는 이 Bash가 작성하는 모든 프로세스에 상속됩니다.

Bash 환경 상세

Bash의 또 다른 변수는 내부 변수입니다.Bash는 단순한 대화형 셸이 아니기 때문에 스크립트 인터프리터이며 다른 인터프리터(Python 등)와 마찬가지로 자체 변수 집합을 유지할 수 있습니다.(Python과 달리) Bash는 문자열 변수만 지원합니다.

은 Bash입니다.name=value이러한 변수는 Bash 내부에 존재하며 운영 체제에서 유지되는 환경 변수와는 관계가 없습니다.

파라미터 상세(변수 포함)

Bash 레퍼런스 매뉴얼에 따라 다음 사항도 유의해야 합니다.

Shell Parameters(쉘 파라미터)에서 설명한 바와 같이 간단한 명령어 또는 기능의 환경은 파라미터 할당으로 프리픽스를 붙임으로써 일시적으로 증강할 수 있습니다.이러한 할당문은 해당 명령어로 표시되는 환경에만 영향을 줍니다.


정리하면:

  • export는, operating.operating system 의 를 설정하기 사용합니다.이 변수는 이후 현재 Bash 프로세스에서 생성된 모든 하위 프로세스에서 사용할 수 있습니다.
  • Bash 변수 표기법(name=value)은 bash의 현재 프로세스에서만 사용할 수 있는 로컬 변수를 설정하는 데 사용됩니다.
  • 다른 명령어를 앞에 붙이는 Bash 변수 표기법에서는 해당 명령어 범위에 대해서만 환경변수가 생성됩니다.

수용된 답변은 이를 의미하지만 셸 빌트인에 대한 연결을 명확하게 하고 싶습니다.

한 바와 같이, 미미 as as as as 。export는 셸과 아이 모두에게 변수를 사용할 수 있도록 합니다. ifexport변수는 셸에서만 사용할 수 있으며 빌트인만 액세스할 수 있습니다.

그것은,

tango=3
env | grep tango # prints nothing, since env is a child process
set | grep tango # prints tango=3 - "type set" shows `set` is a shell builtin

UNIX를 만든 Brian Kernighan과 Rob Pike의 두 사람은 그들의 책 "유닉스 프로그래밍 환경"에서 이것을 설명합니다.구글에서 제목을 검색하면 PDF 버전을 쉽게 찾을 수 있습니다.

은 섹션셸 변수를 , '3.6'의 을 맞추고 .export명령어를 입력합니다.

변수 값을 하위 쉘에서 액세스할 수 있도록 하려면 셸의 내보내기 명령을 사용해야 합니다.(변수 값을 서브셸에서 부모 셸로 내보낼 수 없는 이유를 생각할 수 있습니다).

다음은 또 다른 예입니다.

VARTEST="value of VARTEST" 
#export VARTEST="value of VARTEST" 
sudo env | grep -i vartest 
sudo echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}" 
sudo bash -c 'echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"'  

VARTEST 내보내기를 사용해야만 VARTEST 값이 sudo bash -c '...!

상세한 예에 대해서는, 다음을 참조해 주세요.

환경(env)에 있는 내보내기 변수와 환경에 없는 내보내기되지 않은 변수의 차이를 표시하기 위해 다음과 같이 하십시오.

이렇게 하면:

$ MYNAME=Fred
$ export OURNAME=Jim

$OURNAME만 env에 표시됩니다.$MYNAME 변수는 env에 없습니다.

$ env | grep NAME
OURNAME=Jim

$MYNAME 변수는 셸에 존재합니다.

$ echo $MYNAME
Fred

기본적으로는 스크립트 내에서 작성된 변수는 현재 셸에서만 사용할 수 있습니다.자녀 프로세스(서브셸)는 설정 또는 변경된 값에 액세스할 수 없습니다.하위 프로세스에서 값을 볼 수 있도록 하려면 export 명령을 사용해야 합니다.

여기서의 기존 답변에 대한 또 다른 귀결점이 있다면, 문제의 문구를 바꿔서 설명하겠습니다.

은요, ' 안 될까요?'입니다export"Does success code run a command that access this variable?" (이 변수에 암묵적으로 액세스하는 명령을 후속 코드가 실행합니까?)라는 질문에 대한 답변과 동일합니다.

적절하게 문서화된 표준 유틸리티의 경우 유틸리티의 man 페이지의 ENVIENT 섹션에서 이에 대한 답을 찾을 수 있습니다.를 들어 매뉴얼페이지에는 다음과 같이 기재되어 있습니다.GIT_PAGER는, 「」의 복수 을 참조하기 합니다.git★★★★★★★★★★★★★★★★,

# XXX FIXME: buggy
branch="main"
GIT_PAGER="less"
git log -n 25 --oneline "$branch"
git log "$branch"

를 사용하지 때문에 동작하지 .export GIT_PAGER(물론 시스템이 변수를 이미 다른 곳으로 내보낸 것으로 선언한 경우 버그는 재현할 수 없습니다.)

우리는 명시적으로 그 변수를 언급하고 있다.$branch및 , 。git branchanywhere(이름도 소문자로 표기되어 있기 때문에 알 수 있지만, 많은 초보자도 개인 변수에 대소문자를 잘못 사용합니다!자세한 내용은 "Bash 및 셸 스크립트 변수 대문자 수정"을 참조하십시오.)export branch.

올바른 코드는 다음과 같습니다.

branch="main"
export GIT_PAGER="less"
git log -n 25 --oneline "$branch"
git log -p "$branch"

각 으로 붙일 ).git

branch="main"
GIT_PAGER="less" git log -n 25 --oneline "$branch"
GIT_PAGER="less" git log -p "$branch"

명확하지 않은 경우 셸 스크립트 구문

var=value command arguments

로 설정하다var로로 합니다.value

command arguments

그것을 에 it it and에 it it and and it it and 。command하위 프로세스를 수행한 후 이전 값으로 되돌립니다. 이 값은 정의되지 않거나 다른 값(공백일 수 있음)으로 정의될 수 있으며 이전 값인 경우 보고되지 않을 수 있습니다.

내부 툴, 임시 툴 또는 문서화가 불충분한 툴의 경우 해당 툴이 환경을 사일런트하게 검사하는지 여부만 파악하면 됩니다.특정 사용 사례(예: 암호, 인증 토큰 또는 기타 비밀 정보를 컨테이너 또는 격리된 환경에서 실행 중인 프로세스에 전달하는 등)를 제외하고는 이 작업이 실제로 중요한 경우가 거의 없습니다.

하며 코드에 수 " " "를 .getenv시스템 콜(또는 Windows에서는 애도의 뜻을 표합니다),getenv_s,w_getenv 언어Ruby 는, 「Perl」(Perl) 「Ruby」(루비)를 참조해 ENV Python을 os.environ, (를 들어 「」라고 하는 것도 주의해 주세요. from os import environ as foo foo의 에일리어스가 되었습니다.os.environ [ Node ]에서 [Node ]를 찾습니다process.env는 C를 envp(단, 이것은 의 세 (즉, '세 번째 인수')를main에, 에, 에, 에argc ★★★★★★★★★★★★★★★★★」argv; 언어를 사용하면 원하는 대로 부를 수 있습니다.) 스크립트와 같이)의또는 에 따라 .env. 되어 있지 않지만 에 발견 가능한 이 있습니다 를 .일반적으로 스크립트의 선두 부근에 있습니다.★★★★★★★★★★★★★★★★★★,?=기본 할당 매개 변수 확장입니다.

데모를 하여 Python을 셸 합니다.$NICKNAME설정되지 않은 경우 기본값으로 돌아갑니다.

#!/bin/sh
NICKNAME="Handsome Guy"
demo () {
    python3 <<\____
from os import environ as env
print("Hello, %s" % env.get("NICKNAME", "Anonymous Coward"))
____
}
demo
# prints "Hello, Anonymous Coward"
# Fix: forgot export
export NICKNAME
demo
# prints "Hello, Handsome Guy"

의 접선적 발언으로, 른른른른른른른른, ever ever ever ever ever ever시 ever ever ever ever ever ever ever ever ever ever ever ever ever as as as as ever ever ever ever ever ever ever ever ever 만 있으면 된다는 것을 다시 한 번 강조합니다.export·컬트·, 카고 컬트 코드.

# XXX FIXME: redundant exports
export PATH="$HOME/bin:$PATH"
export PATH="/opt/acme/bin:$PATH"

"사용할 수 없습니다"라고 선언되어 .PATH으로서, 은 더 잘 있습니다.

PATH="$HOME/bin:$PATH"
PATH="/opt/acme/bin:$PATH"

또는 아마도 다음과 같은 것을 리팩터링 했을 것이다.

for p in "$HOME/bin" "/opt/acme/bin"
do
    case :$PATH: in
     *:"$p":*) ;;
     *) PATH="$p:$PATH";;
    esac
done
# Avoid polluting the variable namespace of your interactive shell
unset p

하면 되는 것을 방지할 수 있습니다.PATH.

설명에서 명시적으로 언급하지는 않았지만 모든 변수가 하위 프로세스에 복사되므로 내부 bash에서 하위 셸을 생성할 때 내보내기를 사용할 필요는 없습니다.

언급URL : https://stackoverflow.com/questions/1158091/defining-a-variable-with-or-without-export

반응형