Programing

"#! / usr / bin / env python"을 사용하여 python에 인수를 전달할 수 없습니다.

lottogame 2020. 11. 18. 08:21
반응형

"#! / usr / bin / env python"을 사용하여 python에 인수를 전달할 수 없습니다.


직접 실행 가능한 파이썬 스크립트가 필요했기 때문에 #!/usr/bin/env python. 그러나 버퍼링되지 않은 출력도 필요하므로 시도 #!/usr/bin/env python -u했지만 python -u: no such file or directory.

그 발견 #/usr/bin/python -u일을하지만, 나는 그것이 얻을 필요가 python있는이 PATH가상 지원하기 위해 env환경.

내 옵션은 무엇입니까?


이를 활성화하려면 환경 변수를 사용하는 것이 좋습니다. 파이썬 문서 참조 : http://docs.python.org/2/using/cmdline.html

귀하의 경우 :

export PYTHONUNBUFFERED=1
script.py

일부 환경에서 env는 인수를 분할하지 않습니다. 따라서 환경은 경로에서 "python -u"를 찾고 있습니다. sh를 사용하여 작업 할 수 있습니다. shebang을 다음 코드 줄로 바꾸면 모든 것이 잘 될 것입니다.

#!/bin/sh
''''exec python -u -- "$0" ${1+"$@"} # '''
# vi: syntax=python

추신 우리는 sh의 경로에 대해 걱정할 필요가 없습니다.


Linux에서 shebang을 사용하면 인터프리터 이름 뒤의 나머지 줄 전체가 단일 인수로 해석됩니다. python -u전달됩니다 env사용자가 입력했던 것처럼 : /usr/bin/env 'python -u'. /usr/bin/env바이너리에 대한 검색이라는 python -u하나가되지이다.


shebang 줄에 인수를 전달하는 것은 표준이 아니며 실험 한대로 Linux에서 env와 함께 작동하지 않습니다. bash의 솔루션은 내장 명령 "set"을 사용하여 필수 옵션을 설정하는 것입니다. 파이썬 명령으로 stdin의 버퍼링되지 않은 출력을 설정하기 위해 똑같이 할 수 있다고 생각합니다.

my2c


다음은 / usr / bin / env의 대체 스크립트로, / bin / bash를 기반으로하고 실행 경로에서 공백이 허용되지 않는다는 제한과 함께 해시 뱅 라인에서 인수 전달을 허용합니다. 나는 그것을 "envns"(env No Spaces)라고 부른다.

#!/bin/bash

ARGS=( $1 )  # separate $1 into multiple space-delimited arguments.
shift # consume $1

PROG=`which ${ARGS[0]}`
unset ARGS[0] # discard executable name

ARGS+=( "$@" ) # remainder of arguments preserved "as-is".
exec $PROG "${ARGS[@]}"

이 스크립트가 / usr / local / bin / envns에 있다고 가정하면 다음과 같은 shebang 라인이 있습니다.

#!/usr/local/bin/envns python -u

Ubuntu 13.10 및 cygwin x64에서 테스트되었습니다.


이것은 약간 구식 일 수 있지만 env (1) 매뉴얼은 그 경우 '-S'를 사용할 수 있다고 알려줍니다.

#!/usr/bin/env -S python -u

FreeBSD에서 꽤 잘 작동하는 것 같습니다.


이것은 kludge이며 bash가 필요하지만 작동합니다.

#!/bin/bash

python -u <(cat <<"EOF"
# Your script here
print "Hello world"
EOF
)

Larry Cai의 답변을 바탕으로 env명령 줄에서 직접 변수를 설정할 수 있습니다. -u, PYTHONUNBUFFERED이전에 동등한 설정 으로 대체 할 수 있습니다 python.

#!/usr/bin/env PYTHONUNBUFFERED="YESSSSS" python

RHEL 6.5에서 작동합니다. 의 기능이 env거의 보편적 이라고 확신합니다 .


최근 env에이 문제를 해결하기 위해의 GNU Coreutils 버전에 대한 패치를 작성했습니다 .

http://lists.gnu.org/archive/html/coreutils/2017-05/msg00018.html

이 경우 다음을 수행 할 수 있습니다.

#!/usr/bin/env :lang:--foo:bar

env will split :lang:foo:--bar into the fields lang, foo and --bar. It will search PATH for the interpreter lang, and then invoke it with arguments --foo, bar, plus the path to the script and that script's arguments.

There is also a feature to pass the name of the script in the middle of the options. Suppose you want to run lang -f <thecriptname> other-arg, followed by the remaining arguments. With this patched env, it is done like this:

#!/usr/bin/env :lang:-f:{}:other-arg

The leftmost field which is equivalent to {} is replaced with the first argument that follows, which, under hash bang invocation, is the script name. That argument is then removed.

Here, other-arg could be something processed by lang or perhaps something processed by the script.

To understand better, see the numerous echo test cases in the patch.

I chose the : character because it is an existing separator used in PATH on POSIX systems. Since env does PATH searching, it's vanishingly unlikely to be used for a program whose name contains a colon. The {} marker comes from the find utility, which uses it to denote the insertion of a path into the -exec command line.

참고URL : https://stackoverflow.com/questions/3306518/cannot-pass-an-argument-to-python-with-usr-bin-env-python

반응형