Intenté lo siguiente pero no parece funcionar:
$ cat script.sh
#!/bin/env -i /bin/sh
/bin/env
$ script.sh
/bin/env: invalid option -- ' '
Try `/bin/env --help' for more information.
bash
shell-script
env
balki
fuente
fuente
Respuestas:
La razón por la que esto no funciona es porque lo ve
-i /bin/sh
como un argumento único paraenv
. Por lo general, esto sería 2 argumentos,-i
y/bin/sh
. Esto es solo una limitación del shebang. No hay forma de evitarlo.Sin embargo, aún puede realizar esta tarea, solo de una manera diferente.
Si desea que el script mismo realice esta tarea, y no tiene que hacer algo así
env -i script.sh
, puede hacer que el script se vuelva a ejecutar.Esto hará que el script se vuelva a ejecutar solo si
CLEANED
no se establece la variable de entorno. Luego, en re-exec, establece la variable para asegurarse de que no entre en un bucle.fuente
env
Los GNU coreutils ahora tienen una opción-S
para solucionar problemas similares a este pero no exactamente lo mismo. Por ejemplo#!/usr/bin/env -S perl -T
.#!/usr/bin/env -S -i /bin/sh
. Tenga en cuenta los problemas de portabilidad.Ejecute su script con
env -i
:Y el guión como siempre:
Si quieres correr con un entorno limpio sin decirlo explícitamente cuando corres. Eduardo Ivanec da algunas ideas en esta respuesta , puede llamar recursivamente a su script
exec
cuando el entorno no está limpio (por ejemplo, $ HOME está definido):fuente
Con bash, puedes hacerlo así:
Los comandos
set -e
yset -u
no son estrictamente necesarios, pero los incluyo para demostrar que este enfoque no se basa en acceder a variables no establecidas (como, por ejemplo, lo[ "$HOME" != "" ]
haría) y es compatible con unaset -e
configuración.Probar la
HOME
variable debería ser seguro porque bash ejecuta scripts en modo no interactivo, es decir, los archivos de configuración como~/.bashrc
(donde se pueden establecer variables de entorno) no se obtienen durante el inicio.Salida de ejemplo:
fuente
Lamentablemente, no funcionará de esa manera: Linux lo considera
-i /bin/sh
como un argumento para pasarenv
(ver Shebang ).fuente
La limitación shebang de 2 argumentos de Linux (interpeter + argumento único) se observa en la mayoría de las respuestas, pero decir que esto no se puede hacer es incorrecto: solo necesita cambiar a un intérprete que pueda hacer algo útil con un solo argumento:
Lo que esto hace es invocar
perl
con un script de una línea (-e
) que borra%ENV
(más barato queenv -i
) e invocaexec /bin/sh
, citando correctamente los argumentos. Seperl
puede agregar más lógica, si es necesario (aunque no mucho en Linux ya que está limitado aBINPRM_BUF_SIZE
caracteres, lo que probablemente sea 128)Lamentablemente, esto es específico de Linux, no funcionará en un sistema que permita múltiples argumentos shebang: - /
perl
procesa esta cadena como un argumento único, por lo que no se cita arriba como lo haría normalmenteperl -e ...
desde la línea de comando (si agregara comillas, estas se conservan, perl ve solo una cadena literal, con advertencias sobre ella se quejará de una inutilidad constante).También tenga en cuenta que hay un ligero cambio en el comportamiento cuando se usa de esta manera,
@ARGV
normalmente contiene solo los argumentos y$0
contiene el script, pero con este shebang$ARGV[0]
está el nombre del script (y$0
es-e
) que lo hace un poco más fácil.También puede resolver esto con un intérprete que "reprocese" su línea de comando (sin un
-c
argumento adicional ) que el antiguo AT&Tksh93
hace:aunque tal vez
ksh
no sea tan común hoy en día ;-)(
bash
tiene una característica similar con--wordexp
, pero es "indocumentada" en las versiones donde funciona, y no está habilitada en el momento de la compilación en las versiones donde está documentada: - / Tampoco puede usarse para esto ya que necesita dos argumentos. ..)Además, efectivamente una variación en las respuestas de @Patrick y @ maxschlepzig:
En lugar de usar una nueva variable, esta usa la variable especial "
_
", si no está configurada exactamente como "bash", entonces reemplace el scriptexec
usando-a
para hacerARGV[0]
(y por lo tanto$_
) solo "bash", y usando-c
para limpiar el entorno.Alternativamente, si es aceptable limpiar el entorno al comienzo del script (solo bash):
Eso usa
compgen
(ayudante de finalización) para enumerar los nombres de todas las variables de entorno exportadas, yunset
las envía de una vez.Consulte también Múltiples argumentos en shebang para obtener más detalles sobre el problema general del comportamiento shebang.
fuente