Por que posso passar argumentos para /usr/bin/env neste caso?

Por que posso passar argumentos para /usr/bin/env neste caso?

eu li emoutra respostaque não consigo passar argumentos para o intérprete do que estou dando /usr/bin/env:

Outro problema potencial é que o #!/usr/bin/envtruque não permite passar argumentos para o intérprete (além do nome do script, que é passado implicitamente).

No entanto, parece que consigo, porque awkestá quebrando quando não dou o -fsinalizador e é corrigido quando dou o -fsinalizador, enquanto uso /usr/bin/env:

Primeiro, sem a -fbandeira:

$ 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

Em segundo lugar, com a -fbandeira:

$ 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"
  • Então, se de acordo com oresposta vinculadaNão consigo passar sinalizadores para o intérprete, por que consigo passar o -fsinalizador para awk?

Estou correndo macOS:

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

Responder1

Alguns Unices, principalmente o macOS (e até 2005, o FreeBSD), permitirão isso, enquanto o Linux não, mas...

Se alguém usar o envutilitário de uma versão recente do pacote GNU coreutils (8.30+), ele possui uma -Sopção não padrão que permite fornecer vários argumentos em #!linhas.

A pergunta oposta:Linha Shebang com comando `#!/usr/bin/env --argument` falha no Linux

Responder2

Você não podeportávelpassar vários argumentos para o intérprete. Em particular, o Linux não suporta isso.

Algumas variantes do Unix suportam mais de um argumento na linha shebang. Este é o caso dos sistemas macOS modernos e de alguns outros. VerPágina de portabilidade de shell de Sven MascheckparaTabela de comparação de variantes Unixe muita informação histórica.


Se você deseja ter um script awk portátil, não há uma solução legal. #!/usr/bin/enve #!/bin/shsão as únicas linhas shebang que são portáveis ​​na prática: dependendo da variante Unix, awkpodem estar em /binou /usr/bin, ou em alguns outros locais (por exemplo, /usr/xpg4/bin/awkno Solaris para obter um POSIX - o que está em /usr/biné para aplicativos legados). Como #!/usr/bin/env awk -fnão funciona de forma portável, isso deixa #!/bin/sh. ( /bin/shpode ser um shell Bourne herdado em vez de um shell POSIX moderno, mas qualquer plataforma Unix tem algo lá na prática.) A ideia é escrever umpoliglota, ou seja, um script que shinterpreta como instruções para executar o awk e que o awk interpreta como o script desejado. Isso funciona até mesmo em sistemas que não reconhecem linhas shebang, mas o padrão é shpara execução de script (alguns unices antigos ou alguma área de usuário semelhante ao Unix em kernels não-Unix).

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

(Se a portabilidade para unidades antigas for uma preocupação, consultePágina de Sven Mascheckno "$@"suporte e considere usá-lo ${1+"$@"}.)

informação relacionada