Unter Linux ist der Shebang nicht sehr flexibel. Laut mehreren Antworten ( Stephen Kitts Antwort und Jörg W. Mittag ) gibt es keine Möglichkeit, mehrere Argumente in einer Shebang-Zeile zu übergeben.
Ich bin nicht sicher, ob es für irgendjemanden von Nutzen sein wird, aber ich habe ein kurzes Skript geschrieben, um das fehlende Feature zu implementieren. Siehe https://gist.github.com/loxaxs/7cbe84aed1c38cf18f70d8427bed1efa .
Es ist auch möglich, eingebettete Problemumgehungen zu schreiben. Im Folgenden stelle ich vier sprachunabhängige Problemumgehungen vor, die auf dasselbe Testskript angewendet wurden, und das Ergebnis wird jeweils gedruckt. Ich nehme an, dass das Skript ausführbar ist und sich in befindet /tmp/shebang
.
Umhüllen Ihres Skripts mit einem Bash-Heredoc innerhalb der Prozessersetzung
Soweit ich weiß, ist dies der zuverlässigste sprachunabhängige Weg, dies zu tun. Es erlaubt das Übergeben von Argumenten und erhält die Standardeinstellung. Der Nachteil ist, dass der Interpreter den (realen) Speicherort der gelesenen Datei nicht kennt.
#!/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
) "$@"
Der Aufruf echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
druckt:
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
Beachten Sie, dass die Prozessersetzung eine spezielle Datei erzeugt. Dies ist möglicherweise nicht für alle ausführbaren Dateien geeignet. Zum Beispiel #!/usr/bin/less
beschwert sich:/dev/fd/63 is not a regular file (use -f to see it)
Ich weiß nicht, ob es möglich ist, Heredoc innerhalb der Prozessersetzung im Bindestrich zu haben.
Packen Sie Ihr Skript in einen einfachen Heredoc
Kürzer und einfacher, aber Sie können nicht über stdin
Ihr Skript darauf zugreifen, und der Interpreter muss in der Lage sein, ein Skript zu lesen und auszuführen 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
Der Aufruf echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
druckt:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\\ uses\\ \\\\escapes\\\\']
__debug__ :: True
PYTHON_SCRIPT_END
Benutze awk system()
call aber ohne Argumente
Übergibt den Namen der ausgeführten Datei korrekt, aber Ihr Skript empfängt nicht die Argumente, die Sie ihm geben. Beachten Sie, dass awk die einzige mir bekannte Sprache ist, deren Interpreter standardmäßig unter Linux installiert ist und deren Anweisungen standardmäßig über die Befehlszeile gelesen werden.
#!/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")
Der Aufruf echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
druckt:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: []
__debug__ :: False
PYTHON_SCRIPT_END
Verwenden Sie den system()
Aufruf awk 4.1+ , sofern Ihre Argumente keine Leerzeichen enthalten
Schön, aber nur, wenn Sie sicher sind, dass Ihr Skript nicht mit Argumenten aufgerufen wird, die Leerzeichen enthalten. Wie Sie sehen, werden Ihre Argumente, die Leerzeichen enthalten, geteilt, es sei denn, die Leerzeichen werden maskiert.
#!/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")
Der Aufruf echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \\escapes\\'
druckt:
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
Für awk-Versionen unter 4.1 müssen Sie die Zeichenfolgenverkettung in einer for-Schleife verwenden (siehe Beispielfunktion https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html) .