¿Por qué puedo pasar argumentos a /usr/bin/env en este caso?

¿Por qué puedo pasar argumentos a /usr/bin/env en este caso?

leí enotra respuestaque no puedo pasar argumentos al intérprete de los que le estoy dando a /usr/bin/env:

Otro problema potencial es que el #!/usr/bin/envtruco no permite pasar argumentos al intérprete (aparte del nombre del script, que se pasa implícitamente).

Sin embargo, parece que puedo hacerlo, porque awkse rompe cuando no le doy la -fbandera y se arregla cuando le doy la -fbandera, mientras uso /usr/bin/env:

Primero, sin la -fbandera:

$ cat wrap_in_quotes
#!/usr/bin/env awk
# wrap each line in quotes
# usage: wrap_in_quotes [ file ... ]
{ print "\""$0"\"" }
$ echo foobar | ./wrap_in_quotes
awk: syntax error at source line 1
 context is
     >>> . <<< /wrap_in_quotes
awk: bailing out at source line 1

Segundo, con la -fbandera:

$ vim wrap_in_quotes
$ cat wrap_in_quotes
#!/usr/bin/env awk -f
# wrap each line in quotes
# usage: wrap_in_quotes [ file ... ]
{ print "\""$0"\"" }
$ echo foobar | ./wrap_in_quotes
"foobar"
  • Entonces, si según elrespuesta vinculadaNo puedo pasar indicadores al intérprete, ¿por qué puedo pasar el -findicador a awk?

Estoy corriendo macOS:

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.1
BuildVersion:   16B2657

Respuesta1

Algunos Unices, sobre todo macOS (y hasta 2005, FreeBSD), permitirán esto, mientras que Linux no, pero...

Si se usa la envutilidad de una versión reciente del paquete GNU coreutils (8.30+), tiene una -Sopción no estándar que permite proporcionar múltiples argumentos en #!líneas.

La pregunta contraria:La línea Shebang con el comando `#!/usr/bin/env --argument` falla en Linux

Respuesta2

No puedesportátilmentepasar múltiples argumentos al intérprete. En particular, Linux no lo admite.

Algunas variantes de Unix admiten más de un argumento en la línea shebang. Este es el caso de los sistemas macOS modernos y algunos otros. VerPágina de portabilidad de shell de Sven MascheckparaTabla comparativa de variantes de Unixy mucha información histórica.


Si desea tener un script awk portátil, no existe una solución clara. #!/usr/bin/envy #!/bin/shson las únicas líneas shebang que son portátiles en la práctica: dependiendo de la variante de Unix, awkpueden estar en /bino /usr/bin, o en algunas otras ubicaciones (por ejemplo, /usr/xpg4/bin/awken Solaris para obtener uno POSIX; el de /usr/bines para aplicaciones heredadas). Como #!/usr/bin/env awk -fno funciona de forma portátil, eso deja #!/bin/sh. ( /bin/shpuede ser un shell Bourne heredado en lugar de un shell POSIX moderno, pero cualquier plataforma Unix tiene algo allí en la práctica). La idea es escribir unpolígloto, es decir, un script que shse interpreta como instrucciones para ejecutar awk y que awk se interpreta como el script deseado. Esto incluso funciona en sistemas que no reconocen líneas shebang pero que de forma predeterminada shejecutan scripts (algunos Unices antiguos o algunas áreas de usuario similares a Unix en kernels que no son Unix).

#!/bin/sh
"exec" "awk" "-f" "$0" "$@" && 0 {}
… # awk script here

(Si le preocupa la portabilidad a unidades antiguas, consulteLa página de Sven Maschecken "$@"soporte y considere usar ${1+"$@"}en su lugar.)

información relacionada