set, export 및 env의 차이점은 무엇이며 언제 사용해야합니까?


112

나는 종종 bash 스크립트를 강타하고 변수를 설정하는 몇 가지 방법이 있다는 것을 알게됩니다.

key=value
env key=value
export key=value

스크립트 또는 단일 명령 안에있을 때 (예를 들어, 올바른 와인 접두사를 설정하기 위해 종종 와인 런처와 변수를 연결합니다) 이들은 완전히 상호 교환 가능한 것처럼 보이지만 반드시 그렇지는 않습니다.

이 세 가지 방법의 차이점은 무엇이며 각 방법을 구체적으로 사용하고 싶을 때의 예를들 수 있습니까?

확실히 관련 `VAR = ...`와`수출 VAR = ...`사이의 차이점은 무엇입니까? 하지만 env이것에 얼마나 적합한 지 알고 싶습니다. 각각의 장점을 보여주는 몇 가지 예도 좋습니다. :)


5
참고 export key=value구문을 확장하고 휴대용 스크립트 (예에서 사용할 수 없습니다 #! /bin/sh).
Simon Richter

답변:


110

구체적인 예를 살펴 보겠습니다. 이 grep명령은 환경 변수를 사용하여 GREP_OPTIONS기본 옵션을 설정합니다.

지금. 파일 test.txt에 다음 줄이 포함되어 있다고 가정합니다 .

line one
line two

명령 grep one test.txt을 실행하면

line one

-v옵션으로 grep을 실행하면 일치하지 않는 행이 반환되므로 출력은

line two

이제 환경 변수로 옵션을 설정하려고합니다.

  1. 없이 설정 한 환경 변수 export는 호출중인 명령의 환경에서 상속되지 않습니다.

    GREP_OPTIONS='-v'
    grep one test.txt
    

    결과:

    line one

    분명히이 옵션 -v은에 전달되지 않았습니다 grep.

    셸에서만 사용할 변수를 설정하는 경우 (예 : for i in * ; do내 보내지 않으려는 경우)이 양식을 사용 하려고합니다 $i.

  2. 그러나 변수는 해당 특정 명령 행의 환경으로 전달되므로 다음을 수행 할 수 있습니다.

    GREP_OPTIONS='-v' grep one test.txt

    예상되는 결과를 반환합니다

    line two

    시작된이 특정 프로그램 인스턴스의 환경을 일시적으로 변경하기 위해이 양식을 사용합니다.

  3. 변수를 내 보내면 변수가 상속됩니다.

    export GREP_OPTIONS='-v'
    grep one test.txt
    

    지금 돌아온다

    line two

    쉘에서 이후에 시작된 프로세스를 사용하기 위해 변수를 설정하는 가장 일반적인 방법입니다.

  4. 이것은 모두 bash에서 수행되었습니다. exportbash 내장입니다. VAR=whateverbash 구문입니다. env반면에, 그 자체가 프로그램입니다. 경우 env라고하며, 다음과 같은 사항이 발생합니다 :

    1. 명령 env이 새로운 프로세스로 실행됩니다
    2. env 환경을 수정하고
    3. 인수로 제공된 명령을 호출합니다. env프로세스는로 대체 command방법.

    예:

    env GREP_OPTIONS='-v' grep one test.txt

    이 명령은 (i) env 및 (ii) grep이라는 두 가지 새로운 프로세스를 시작합니다 (실제로 두 번째 프로세스가 첫 번째 프로세스를 대체 함). grep프로세스 의 관점 에서 결과는 실행 중과 정확히 동일합니다.

    GREP_OPTIONS='-v' grep one test.txt

    그러나 bash 외부에 있거나 다른 쉘을 시작하지 않으려는 경우 (예 : 호출 exec()대신 함수 계열을 사용하는 경우)이 관용구를 사용할 수 있습니다 system().

추가 참고 사항 #!/usr/bin/env

이 때문에 관용구 #!/usr/bin/env interpreter가 아닌 이유 가 사용됩니다 #!/usr/bin/interpreter. 쉘처럼 변수 를 검색 한 다음 명령 실행으로 대체env 하는 execvp()기능을 사용하기 때문에 프로그램에 대한 전체 경로가 필요하지 않습니다 . 따라서 인터프리터 (perl 또는 python과 같은)가 경로에 "있는"위치를 찾는 데 사용할 수 있습니다.PATH

또한 현재 경로를 수정함으로써 어떤 파이썬 변종이 호출 될지에 영향을 줄 수 있음을 의미합니다. 이것은 다음을 가능하게합니다.

echo -e '#!/usr/bin/bash\n\necho I am an evil interpreter!' > python
chmod a+x ./python
export PATH=.
calibre

Calibre를 시작하는 대신

I am an evil interpreter!

GREP_OPTIONS = '-v'grep one test.txt가 작동하는 이유는 무엇입니까? 나는 '-v'다음에 세미콜론이 필요하다고 생각했지만 (시도했지만 실제로 작동합니다.)
Joe

2
세미콜론을 사용하면 두 개의 개별 bash 명령으로 해석됩니다. 첫 번째는 변수를 내 보내지 않고 설정하고 두 번째는 변수를 내 보내지 않은 환경에서 시작합니다. 그러나 세미콜론이 없으면이 명령은 로컬 환경을 설정하기 전에 하나의 명령 (grep)입니다.
1 월

모든 변수는 어디에서 env왔습니까? 새 쉘을 열면 항상 몇 가지 변수가 있습니다. 어떤 프로그램은 export그 프로그램을 수정해야합니다 .
Pithikos

1
@Pithikos 환경 변수는 "환경 소싱"으로 설정됩니다. 기본적으로 bash는 시스템 전체의 bashrc (또는 profile.d 또는 bash_profile)를 제공합니다. 그런 다음 사용자 ~ / .bashrc (및 / 또는 ~ / .bash_profile)를 제공합니다. 이 파일들 중 하나는 다른 스크립트를 소스로 사용하는 bash 명령을 포함 할 수 있으므로 궁극적으로 환경 변수가 어디서나 나올 수 있습니다.
Eric

5
무엇에 대해 set var=blah?
CMCDragonkai
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.