1
votes

I want to make my shebang enabled POSIX awk programs have more of a standard interface to them -- not using the -v var=val interface but using one that looks like other programs available from the Linux/UNIX command line. The issue that I have encountered is that awk scripts relay flags to awk -- and then awk itself has first crack at interpreting those flags. Also, different implementations of awk have different flag options. The end result is that it is nigh impossible to build an awk program with an interface that can just work parsing ARGC, ARGV[] for flags.

So, I end up encapsulating my awk programs in shell -- which adds to my support and testing burden -- and that shell code looks like the following:

arg_core=""
arg_directory=""
arg_module=""
arg_output=""
arg_regmap=""
arg_regpage=""
arg_help=0
arg_version=0
arg_verbose=0
while getopts c:d:m:o:p:r:hvV o
do
        case "$o" in
        c) arg_core="$OPTARG";;
        d) arg_directory="$OPTARG";;
        m) arg_module="$OPTARG";;
        o) arg_output="$OPTARG";;
        p) arg_regpage="$OPTARG";;
        r) arg_regmap="$OPTARG";;
        h) arg_help=1;;
        v) arg_version=1;;
        V) arg_verbose=1;;
        --) break;;
        ?) help >&2
             exit 1;;
        esac
done
shift `expr $OPTIND - 1`

# Handling help and version (verbose option also displays revision
# history and notes) is more easily done outside the getopts loop.
if [ $arg_version -gt 0 ]
then
        version
        [ $arg_verbose -gt 0 ] && rev_history
fi
if [ $arg_help -gt 0 ]
then
        [ $arg_version -gt 0 ] && echo
        help
fi
[ $arg_help -gt 0 -o $arg_version -gt 0 ] && exit 0

awk -v arg_core="$arg_core" -v arg_directory="$arg_directory" -v arg_module="$arg_module" -v arg_output="$arg_output" -v arg_regmap="$arg_regmap" -v arg_regpage="$arg_regpage" -f rffe2tpf.awk -- "$@"

My question is... I want to eliminate the shell script encapsulation and want to do my argument parsing in awk -- and I want to do it portably. (Note... I am not asking, "How do I do getopts in awk?" I am instead asking, "How do I from the shebang in an awk script portably stop awk from parsing flags?") Is there a way to trick awk or the shebang into accomplishing this goal?

1
GNU awk does have a getop function. Is that what you need?user2350426
@BinaryZebra -- portable to me means that I want to be POSIX compliant. For the present, I want the option to use either gawk or mawk... and I also want my scripts to be relatively future-proof.Michael Back
An awk getopt from not-gnu is not available AFAIK. A POSIX getopts only exists for shell scripts. You are in for a world of hurt. Good luck.user2350426
This is why I use perlNeil Masson
I do not understand why the automatic response to GNU of: "is not POSIX", when, in fact, there is a lot of POSIX compliance effort in most of the programs. Well, I guess that is one of the unsolved mysteries of the Universe.user2350426

1 Answers

1
votes

Posting to stackoverflow has made me think more deeply about the problem, and I believe I have something closer to a solution. If anyone has some "shebang-foo" that I am unaware of that can solve this problem, then I will pick that answer above my own.

Special thanks to BinaryZebra for pointing me to getopt.awk -- as I no longer need to think about rolling my own getopt() implementation.

We may not be able to portably provide the behaviour we want from the shebang, but we are able to significantly limit the amount of code in the shell script to support the behaviour we want. The proposed solution is generic and can be used for all our awk scripts.

I call the following script bawk:

#! /usr/bin/env sh
p=$1
shift
awk -f "$p" -- "$@"

If bawk is placed in our path, it can be used in the awk script's shebang. Here is a test script:

#! /usr/bin/env bawk
BEGIN { for (i=1; i<ARGC; i++) print ARGV[i] }

Output:

$ ./foo.awk -abc -1 -2 -3
-abc
-1
-2
-3