No Linux, o shebang não é muito flexível; de acordo com várias respostas ( resposta de Stephen Kitt e Jörg W Mittag's ), não há maneira designada de passar múltiplos argumentos em uma linha shebang.
Não tenho certeza se será útil para qualquer pessoa, mas escrevi um pequeno script para implementar o recurso que falta. Consulte o link .
Também é possível escrever soluções incorporadas. A seguir, apresento quatro soluções alternativas aplicadas ao mesmo script de teste e o resultado que cada um imprime. Eu suponho que o script é executável e está em /tmp/shebang
.
Envolvendo o seu script em um processo de substituição dentro do processo
Até onde eu sei, esta é a maneira mais confiável e independente de linguagem de fazê-lo. Permite passar argumentos e preserva stdin. A desvantagem é que o intérprete não sabe a localização (real) do arquivo que lê.
#!/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
) "$@"
Chamando echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \escapes\'
imprime:
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
Observe que a substituição do processo produz um arquivo especial. Isso pode não atender a todos os executáveis. Por exemplo, #!/usr/bin/less
reclama: /dev/fd/63 is not a regular file (use -f to see it)
Eu não sei se é possível ter heredoc dentro da substituição do processo em traço.
Envolvendo seu script em um heredoc simples
Mais curto e simples, mas você não poderá acessar stdin
do seu script e exigirá que o intérprete possa ler e executar um script em 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
Chamando echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \escapes\'
imprime:
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\ uses\ \\escapes\\']
__debug__ :: True
PYTHON_SCRIPT_END
Use awk system()
chamada mas sem argumentos
Passa corretamente o nome do arquivo executado, mas seu script não recebe os argumentos que você fornece.
Note que o awk é a única linguagem que conheço, cujo interpretador está instalado no linux por padrão e lê suas instruções a partir da linha de comando por padrão.
#!/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")
Chamando echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \escapes\'
imprime:
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: []
__debug__ :: False
PYTHON_SCRIPT_END
Use o awk 4.1+ system()
call, desde que seus argumentos não contenham espaços
Bom, mas apenas se você tiver certeza de que seu script não será chamado com argumentos que contenham espaços. Como você pode ver, seus argumentos contendo espaços seriam divididos, a menos que os espaços tenham escapado.
#!/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")
Chamando echo -e 'aa\nbb' | /tmp/shebang 'arg1' 'arg2 contains spaces' 'arg3\ uses\ \escapes\'
imprime:
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
Para versões awk abaixo de 4.1, você terá que usar a concatenação de strings dentro de um loop for, veja a função exemplo link .