В Linux шебанг не очень гибкий; согласно множественным ответам (ответ Стивена Китта и Йорга Миттага ), не существует определенного способа передачи нескольких аргументов в строке Шебанга.
Я не уверен, будет ли это кому-нибудь полезно, но я написал короткий скрипт для реализации недостающей функции. См. Https://gist.github.com/loxaxs/7cbe84aed1c38cf18f70d8427bed1efa .
Также возможно написать встроенные обходные пути. Ниже я представляю четыре не зависящих от языка обходных пути, примененных к одному и тому же тестовому сценарию, и результат, который печатает каждый из них. Я полагаю, что скрипт является исполняемым и находится в /tmp/shebang
.
Оборачиваем ваш скрипт в bash heredoc внутри процесса подстановки
Насколько я знаю, это самый надежный, независимый от языка способ сделать это. Это позволяет передавать аргументы и сохраняет стандартный ввод. Недостатком является то, что интерпретатор не знает (реального) местоположения файла, который он читает.
#!/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 - единственный из известных мне языков, чей интерпретатор по умолчанию установлен в linux и по умолчанию читает его инструкции из командной строки.
#!/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
Для версий awk ниже 4.1 вам придется использовать конкатенацию строк внутри цикла for, см. Пример функции https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .