Shebang에서 환경 변수를 어떻게 사용합니까?


34

특정 Python 설치로 실행 해야하는 Python 스크립트가 있습니다. 그것이 작동하도록 shebang을 만드는 방법이 $FOO/bar/MyCustomPython있습니까?

답변:


29

shebang 라인은 매우 제한적입니다. 많은 유닉스 변형 (리눅스 포함)에서는 명령과 단일 인수라는 두 단어 만 가질 수 있습니다. 길이 제한도 있습니다.

일반적인 해결책은 작은 쉘 랩퍼를 작성하는 것입니다. Python 스크립트의 이름을 지정하고 foo.py쉘 스크립트를 옆에 놓고 foo.py호출하십시오 foo. 이 접근법은 Python 스크립트에 특정 헤더가 필요하지 않습니다.

#!/bin/sh
exec "$FOO/bar/MyCustomPython" "$0.py" "$@"

또 다른 유혹적인 접근 방식은 위와 같은 래퍼 스크립트를 작성 #!/path/to/wrapper/script하고 Python 스크립트에 shebang 행으로 넣는 것입니다. 그러나 대부분의 유니스는 셰방 스크립트 체인을 지원하지 않으므로 작동하지 않습니다.

경우 MyCustomPython에 있었다 $PATH, 당신은 사용할 수 env를 찾기 위해 :

#!/usr/bin/env MyCustomPython
import 

또 다른 접근법은 스크립트가 유효한 쉘 스크립트 (올바른 Python 인터프리터 자체를로드 함)와 대상 언어의 유효한 스크립트 (여기서는 Python)가되도록하는 것입니다. 이를 위해서는 대상 언어에 대한 이중 언어 스크립트를 작성하는 방법을 찾아야합니다. Perl에서는 이것을로 알려져 있습니다 if $running_under_some_shell.

#!/bin/sh
eval 'exec "$FOO/bar/MyCustomPerl" -wS $0 ${1+"$@"}'
    if $running_under_some_shell;
use 

파이썬에서 동일한 효과를 얻는 방법은 다음과 같습니다. 쉘에서 "true"는 IS true인수 (두 개의 단일 문자열 무시 유틸리티 :')과 진정한 값을 반환합니다. 파이썬에서 "true"부울로 해석 될 때 참인 문자열이므로, if항상 참이며 문자열 리터럴을 실행 하는 명령입니다.

#!/bin/sh
if "true" : '''\'
then
exec "$FOO/bar/MyCustomPython" "$0" "$@"
exit 127
fi
'''
import 

Rosetta 코드에는 다른 여러 언어로 된 이중 언어 스크립트가 있습니다.


1
@Chris : 모든 것이 작은 따옴표 안에 있습니다. ... 설명해주십시오
스테판 히메네스

1
당신은 피 묻은 마법사입니다 ... 이것은 훌륭합니다. 나는 이것을 사용하여 PYTHONPATH루트 액세스 권한이없는 시스템의 CGI 스크립트에 대한 비표준 위치에서 모듈을로드하기 위해 env 변수 를 편집 했습니다. 생명의 은인. 다시 감사합니다.
wspurgin

12

Shebang 라인은 변수 확장을 거치지 않으므로 $FOO/MyCustomPythondollar-FOO -...라는 실행 파일을 검색 할 때 사용할 수 없습니다.

대안은 shebang이 해석기로 쉘 스크립트를 가리 키도록하는 것입니다. 그런 다음이 쉘 스크립트는 환경 변수를 사용하여 올바른 변수를 찾고 실행할 수 있습니다.

예 : 다음 내용 으로 mypython.sh스크립트를 작성하십시오 /usr/local/bin(또는의 다른 디렉토리 $PATH).

#! /bin/sh
PYTHON="$FOO/bar/MyCustomPython"
exec "$PYTHON" "$@"

당신은 파이썬 스크립트를 통해 실행하려면이 오두막 라인을 사용할 수 있습니다 MyCustomPython통해 mypython.sh:

#!/usr/bin/env mypython.sh

6
사용 $python하지 $PYTHON- 규칙에 따라, 우리는 환경 변수 (호출기, 에디터, SHELL이 ... 투자 $PYTHON스크립트에서 환경 변수 없음) 및 내부 쉘 변수 (BASH_VERSION, RANDOM, ...). 다른 모든 변수 이름에는 하나 이상의 소문자가 포함되어야합니다. 이 규칙은 실수로 환경 및 내부 변수를 무시하지 않도록합니다. 또한 스크립트에 확장자를 사용하지 마십시오. 스크립트는 실행할 수있는 새로운 명령을 정의하며 일반적으로 명령에는 확장명이 제공되지 않습니다.
Chris Down

4

커스텀 파이썬 설치의 절대 경로를 사용하거나에 넣고 $PATH사용할 수 있습니다 #!/usr/bin/env [command]. 그렇지 않으면, 랩퍼를 작성하고 exec예를 들어 프로세스 이미지를 바꾸는 데 사용 하십시오.

#!/bin/bash
exec "$ENV/python" "$@"

3

먼저, 파이썬 버전이 이미 설치된 표준 파이썬 (예 : 추가 모듈)과 어떻게 다른지 결정한 다음 프로그램 시작시 파이썬이 호출되는 방식을 '전환'하십시오.

#!/usr/bin/python
import os
import sys
try:
    import MyCustomModule
except ImportError:
    # only need to use expandvar if you know the string below has an envvar
    custprog = os.path.expandvar("$FOO/bar/MyCustomPython")
    os.execv(custprog, sys.argv) # call alternate python with the same arguments
    raise SystemExit('could not call %s' % custprog)
# if we get here, then we have the correct python interpreter

이를 통해 다른 파이썬 인스턴스에서 프로그램을 호출 할 수 있습니다. 시스템의 파이썬에서 모듈로 가져올 수없는 내장 SQL 라이브러리가있는 인스턴스와 비슷한 것을 수행합니다.


0

당신이 대체 할 수있는 경우 $FOO$FOO/bar/MyCustomPython구체적인 경로 옵션과 함께, 당신은 말할 수있는 env위치를 직접 정의를 설정하여 사용자 정의 파이썬 버전을 조회하는 오두막 선을 PATH그 안에.

#!/usr/bin/env PATH="/path1/to/MyCustomPython:/path2/to/MyCustomPython" python

편집 : PATH 값 할당 주위에 따옴표없이 만 작동하는 것 같습니다.

#!/usr/bin/env PATH=/path1/to/MyCustomPython:/path2/to/MyCustomPython python

5
이것은 모든 유닉스 변형에서 작동하지 않는다는 것을주의하십시오 (예를 들어 리눅스에서는 그렇지 않음). 경로에서 기존 디렉토리를 모두 제거하면 문제가 발생할 수 있습니다.
Gilles 'SO- 악마 그만해'

1
다음 PATH과 같이 확장하는 것이 PATH=$PATH:/path/to/whatever...
좋습니다
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.