2

Can I get arguments that happen to be AWK options passed directly to a pure AWK script?

Example script:

#!/usr/bin/env -S awk -f
BEGIN { if (ARGV[1] == "-h") print "whoop" }

I want ./myscript -h to print whoop. But AWK gets the -h first and prints its usage instead.

Running ./myscript -- -h works but I can't get -- working in the shebang because of the -f.

I know I could use a shell script with AWK in instead.

7
  • I'm not on a Unix that allows the multi argument style #! line that you use, so I can't test this: Add -- at the end of the #! line.
    – Kusalananda
    Mar 12, 2020 at 23:50
  • 3
    @Kusalananda, that would result in env -S awk -f -- ./myscript -h, while what I think they need is env -S awk -f ./myscript -- -h. I think that's what the second to last paragraph is trying to say.
    – ilkkachu
    Mar 12, 2020 at 23:55
  • I think that can't be done with just the #! line, a shell script sounds like a good idea.
    – ilkkachu
    Mar 12, 2020 at 23:57
  • @ilkkachu Yeah, that sounds about right.
    – Kusalananda
    Mar 12, 2020 at 23:57
  • @Kusalananda No Unix allows multi argument style #!. IIRC FreeBSD used to, but that was long time ago.
    – user313992
    Mar 13, 2020 at 6:49

2 Answers 2

4

For the sake of the challenge, it could be done with the FreeBSD env or with GNU env >= 8.30 (already assumed by the OP) in a shebang:

#! /usr/bin/env -S sh -c 'exec awk -f "$0" -- "$@"'
BEGIN { for(i = 1; i < ARGC; i++) print ARGV[i] }
./myscript -h 1 2 3
-h
1
2
3

It doesn't mean that it's a good idea, though.

You could try this, instead:

#! /bin/sh
BEGIN { 2>"/dev/null"
        exec awk -f "$0" "--" "$@"
}
BEGIN { for(i = 1; i < ARGC; i++) print ARGV[i] }

This assumes that you don't have a BEGIN command in your PATH.

3
  • FWIW, coreutils 8.26 env has no -S option.
    – roaima
    Mar 13, 2020 at 9:47
  • 1
    My recommended variant works on any POSIX system, even those which do not support shebangs.
    – user313992
    Mar 13, 2020 at 9:56
  • 1
    @roaima It was committed on the 21st of April 2018, inspired by FreeBSD (github.com/coreutils/coreutils/commit/…)
    – Kusalananda
    Mar 13, 2020 at 10:02
2

If you have GNU awk you can use this

#!/usr/bin/gawk --exec
BEGIN { print "==>",ARGV[1],"<==" }

Sample use

./a -h
 ==> -h <==

I haven't tested it, but the mawk variant appears to use -W exec instead of --exec. GNU gawk claims to support this too, but it doesn't work with #!.

1
  • It may work using the same env -S trick the user is already using.
    – Kusalananda
    Mar 13, 2020 at 7:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.