В Linux шебанг не дуже гнучкий; в відповідно до декількох варіантами відповідей ( відповідь Стівена Кітт в і Йорг W Mittag - х ), там немає призначеного шляху , щоб пройти кілька аргументів на хатину лінії.
Я не впевнений, чи комусь це буде корисно, але я написав короткий сценарій, щоб реалізувати функцію відсутності. Дивіться https://gist.github.com/loxaxs/7cbe84aed1c38cf18f70d8427bed1efa .
Можна також написати вбудовані обхідні шляхи. Нижче я представляю чотири мовно-агностичні вирішення, застосовані до одного і того ж тестового сценарію, і результат кожного друкується. Я гадаю, що сценарій виконується і знаходиться в ньому /tmp/shebang
.
Загортання сценарію в баш гередок всередині процесу заміни
Наскільки мені відомо, це найнадійніший мовно-агностичний спосіб зробити це. Це дозволяє передавати аргументи і зберігає 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 всередині процесу заміни в тирі.
Складання сценарію в простому гередоку
Коротше і простіше, але ви не зможете отримати доступ 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 вам доведеться використовувати конкатенацію рядків усередині a для циклу, див. Приклад функції https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .