9

I read in another answer that I'm not able to pass arguments to the interpreter than I'm giving to /usr/bin/env:

Another potential problem is that the #!/usr/bin/env trick doesn't let you pass arguments to the interpreter (other than the name of the script, which is passed implicitly).

However, it looks like I am able to, because awk is breaking when I don't give it the -f flag and it's fixed when I do give it the -f flag, while using /usr/bin/env:

First, without the -f flag:

$ 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

Second, with the -f flag:

$ 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"
  • So, if according to the linked answer I'm not able to pass flags to the interpreter, why am I able to pass the -f flag to awk?

I'm running macOS:

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.1
BuildVersion:   16B2657
mbigras
  • 3,100
  • 1
    @Fox Your comment is more than two decades out of date. #!/usr/bin/env isn't “becoming rather popular”, it's a decade-old de facto standard. I've seen such discussions in the late 1990s, and already at the time the conclusion was that #!/usr/bin/env was mostly portable but didn't work on a few exotic platforms (SCO, Nextstep). Today Unix platforms without #!/usr/bin/env are exotic and obsolete. Claiming that “it isn't really all that portable either” is just wrong (unless you're targeting non-unix platforms of course). – Gilles 'SO- stop being evil' Apr 28 '17 at 12:39

2 Answers2

13

Some Unices, most notably the macOS (and up until 2005, FreeBSD), will allow for this, while Linux will not, but...

If one use the env utility from a recent release of the GNU coreutils package (8.30+), it has a non-standard -S option that allows for supplying multiple arguments in #! lines.

The opposite question: Shebang line with `#!/usr/bin/env command --argument` fails on Linux

Kusalananda
  • 333,661
3

You cannot portably pass multiple arguments to the interpreter. In particular, Linux doesn't support it.

Some Unix variants do support more than one argument on the shebang line. This is the case on modern macOS systems and a few others. See Sven Mascheck's shell portability page for a Unix variants comparison table and a lot of historical information.


If you want to have a portable awk script, there's no neat solution. #!/usr/bin/env and #!/bin/sh are the only shebang lines that are portable in practice: depending on the Unix variant, awk may be in /bin or /usr/bin, or in some other locations (e.g. /usr/xpg4/bin/awk on Solaris to get a POSIX one — the one in /usr/bin is for legacy applications). Since #!/usr/bin/env awk -f doesn't work portably, that leaves #!/bin/sh. (/bin/sh may be a legacy Bourne shell rather than a modern POSIX shell but any Unix platform has something there in practice.) The idea is to write a polyglot, i.e. a script that sh interprets as instructions to run awk and that awk interprets as the desired script. This even works on systems that don't recognize shebang lines but default to sh for script execution (some antique unices, or some unix-like userland on non-Unix kernels).

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

(If portability to ancient unices is a concern, see Sven Mascheck's page on "$@" support and consider using ${1+"$@"} instead.)

  • So what would you do in my case? I read it's bad form to write a bash script with /usr/bin/env bash that only runs an awk script, except now it seems like that would be the more portable solution. – mbigras Apr 27 '17 at 22:56
  • can you not put the awk script in a file and instead execute awk -f /path/to/that/file? – Jeff Schaller Apr 28 '17 at 01:25
  • "modern FreeBSD" there is FreeBSD until 2005. https://unix.stackexchange.com/a/605761/5132 – JdeBP Aug 22 '20 at 13:12