En Linux, el shebang no es muy flexible; de acuerdo con las respuestas múltiples (la respuesta de Stephen Kitt y la de Jörg W Mittag ), no hay una forma designada para pasar múltiples argumentos en una línea shebang.
No estoy seguro de si será de utilidad para alguien, pero he escrito un breve guión para implementar la función que falta. Ver https://gist.github.com/loxaxs/7cbe84aed1c38cf18f70d8427bed1efa .
También es posible escribir soluciones alternativas integradas. A continuación, presento cuatro soluciones independientes del lenguaje aplicadas al mismo script de prueba y el resultado que imprime cada una. Supongo que el script es ejecutable y está en /tmp/shebang
.
Envolviendo su script en un bash heredoc dentro de la sustitución del proceso
Hasta donde yo sé, esta es la forma más confiable de hacer un lenguaje independiente. Permite pasar argumentos y preserva stdin. El inconveniente es que el intérprete no conoce la ubicación (real) del archivo que lee.
#!/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\\'
Impresiones de llamadas :
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
Tenga en cuenta que la sustitución del proceso produce un archivo especial. Esto puede no adaptarse a todos los ejecutables. Por ejemplo, se #!/usr/bin/less
queja:/dev/fd/63 is not a regular file (use -f to see it)
No sé si es posible tener heredoc dentro de la sustitución del proceso en el tablero.
Envolviendo su script en un simple heredoc
Más corto y simple, pero no podrá acceder stdin
desde su script y requiere que el intérprete pueda leer y ejecutar un script 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\\'
Impresiones de llamadas :
PYTHON_SCRIPT_BEGINNING
input() caused EOFError
argv[0] :: -
argv[1:] :: ['arg1', 'arg2 contains spaces', 'arg3\\ uses\\ \\\\escapes\\\\']
__debug__ :: True
PYTHON_SCRIPT_END
Usa una system()
llamada awk pero sin argumentos
Pasa correctamente el nombre del archivo ejecutado, pero su script no recibirá los argumentos que le dé. Tenga en cuenta que awk es el único idioma que conozco cuyo intérprete está instalado en Linux de forma predeterminada y lee sus instrucciones desde la línea de comandos de forma predeterminada.
#!/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\\'
Impresiones de llamadas :
PYTHON_SCRIPT_BEGINNING
input() 0 :: aa
input() 1 :: bb
argv[0] :: /tmp/shebang
argv[1:] :: []
__debug__ :: False
PYTHON_SCRIPT_END
Use awk 4.1+ system()
llamada , siempre que sus argumentos no contengan espacios
Agradable, pero solo si está seguro de que su script no se llamará con argumentos que contengan espacios. Como puede ver, sus argumentos que contienen espacios se dividirían, a menos que se escapen los espacios.
#!/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\\'
Impresiones de llamadas :
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 las versiones awk inferiores a 4.1, deberá utilizar la concatenación de cadenas dentro de un bucle for, consulte la función de ejemplo https://www.gnu.org/software/gawk/manual/html_node/Join-Function.html .