Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding the awk -f option in shebang line

Tags:

linux

awk

I am reading someone's awk script. Starts with the header #!/usr/bin/env awk -f. The env command does not have a -f option. So, they must be passing the -f option for the awk command. I looked at the man page for awk. It says Awk scans each input file for lines that match any of a set of patterns specified literally in prog or in one or more files specified as -f progfile. With each pattern there can be an associated action that will be performed when a line of a file matches the pattern.

As per my understanding, this means that awk processes the input file(s) by searching for lines with patterns specified in progfile/prog depending on whether or not you use -f option with awk. And based on the patterns used, an associated action is performed on the lines found in the input file(s). My question here is... how does this work while running an awk script file? We're not specifying the progfile in the #!/usr/bin/env awk -f line. What patterns will the awk script use? Or does this mean that we have to pass the progfile when we run the awk script? If that is the case, isn't specifying the -f option in the script redundant? If we don't specify the progfile, will the -f option be ignored by default or throw an error?

To understand this better, I wrote a simple awk script and saved it as test.awk

#!/usr/bin/env awk -f

BEGIN { print "START" }

When I run this, the string "START" gets printed on the screen.

prachis-mbp-2:~ pskhadke$ ./test.awk
START

If I remove the -f option from the first line of the awk script and run it, I get the following error:

prachis-mbp-2:~ pskhadke$./test.awk
awk: syntax error at source line 1
 context is
     >>> . <<< /test.awk

Similarly,

prachis-mbp-2:~ pskhadke$ awk test.awk
awk: syntax error at source line 1
 context is
     >>> test. <<< awk
awk: bailing out at source line 1

So for some reason, it's failing to parse the arguments correctly without the -f option. But why?

like image 331
Prachi Avatar asked Dec 24 '22 11:12

Prachi


1 Answers

The name of the file is appended to the end of the command in the shebang line. Hence the resulting command line effectively executed for a file test.awk with the header #!/usr/bin/env awk -f would be awk -f test.awk, treating test.awk as the script file to execute rather than a data input file.

The best illustration: create a file test with as sole contents #!/bin/rm, make it executable (e.g. chmod 755) and try to execute it by running ./test. Now, where did that file go :)

like image 190
Vincent De Baere Avatar answered Jan 05 '23 20:01

Vincent De Baere