Linux에서 shebang은 매우 유연하지 않습니다. 여러 답변 ( Stephen Kitt의 답변 및 Jörg W Mittag의 )에 따르면, 세방 라인에서 여러 인수를 전달하는 지정된 방법이 없습니다.
누구에게나 사용할 것인지 잘 모르겠지만 부족한 기능을 구현하기 위해 짧은 스크립트를 작성했습니다. https://gist.github.com/loxaxs/7cbe84aed1c38cf18f70d8427bed1efa를 참조 하십시오 .
포함 된 해결 방법을 작성할 수도 있습니다. 벨로우, 나는 같은 테스트 스크립트에 적용되는 4 가지 언어 에 대한 해결책과 각각의 결과를 제시한다. 스크립트가 실행 가능하고에 있다고 가정합니다 /tmp/shebang
.
프로세스 대체 내부의 bash heredoc에 스크립트 래핑
내가 아는 한, 이것이 가장 신뢰할 수있는 언어 독립적 방법입니다. 인수를 전달하고 stdin을 보존합니다. 단점은 인터프리터가 읽는 파일의 (실제) 위치를 모른다는 것입니다.
#!/bin/bash
exec python3 -O <(cat << 'EOWRAPPER'
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
) "$@"
호출 echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
인쇄 :
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /dev/fd/62
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\\ uses\\ \\\\escapes\\\\']
__debug__ :: False
PYTHON_SCRIPT_END
프로세스 대체는 특수 파일을 생성합니다. 모든 실행 파일에 적합한 것은 아닙니다. 예를 들어 다음과 같이 #!/usr/bin/less
불평합니다./dev/fd/63 is not a regular file (use -f to see it)
heredoc을 프로세스 대체 내부에 대시로 넣을 수 있는지 모르겠습니다.
간단한 heredoc에서 스크립트 감싸기
더 짧고 간단하지만 stdin
스크립트에서 액세스 할 수 없으며 인터프리터가에서 스크립트를 읽고 실행할 수 있어야합니다 stdin
.
#!/bin/sh
exec python3 - "$@" << 'EOWRAPPER'
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
try:
print("input() 0 ::", input())
print("input() 1 ::", input())
except EOFError:
print("input() caused EOFError")
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
EOWRAPPER
호출 echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
인쇄 :
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\\ uses\\ \\\\escapes\\\\']
__debug__ :: True
PYTHON_SCRIPT_END
system()
인수없이 awk 호출 사용
실행 된 파일의 이름을 올바르게 전달하지만 스크립트는 사용자가 제공 한 인수를받지 않습니다. awk는 인터프리터가 기본적으로 리눅스에 설치되어 있으며 명령 줄에서 기본적으로 명령을 읽는 유일한 언어입니다.
#!/usr/bin/gawk BEGIN {system("python3 -O " ARGV[1])}
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
호출 echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
인쇄 :
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: []
__debug__ :: False
PYTHON_SCRIPT_END
system()
인수에 공백이 없으면 awk 4.1 이상 호출을 사용하십시오.
훌륭하지만 공백이 포함 된 인수로 스크립트를 호출하지 않을 경우에만 가능합니다. 보시다시피 공백이 포함되지 않은 인수는 공백이 이스케이프되지 않는 한 분할됩니다.
#!/usr/bin/gawk @include "join"; BEGIN {system("python3 -O " join(ARGV, 1, ARGC, " "))}
print("PYTHON_SCRIPT_BEGINNING")
from sys import argv
print("input() 0 ::", input())
print("input() 1 ::", input())
print("argv[0] ::", argv[0])
print("argv[1:] ::", argv[1:])
print("__debug__ ::", __debug__)
# The -O option changes __debug__ to False
print("PYTHON_SCRIPT_END")
호출 echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
인쇄 :
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: ['arg1', 'arg2', 'contains', 'spaces', 'arg3 uses \\escapes\\']
__debug__ :: False
PYTHON_SCRIPT_END
4.1 미만의 awk 버전의 경우 for 루프 내에서 문자열 연결을 사용해야합니다 (예제 함수 https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html 참조) .