I'm working on a script (that will run on OSX, and probably nothing else), that basically just parses the /var/log/accountpolicy.log* logs for authentication times/counts. The initial command is a zgrep executed via sudo, which is piped to awk, executing an awk script. After the command is ran, I use ${PIPESTATUS[@]} to determine if anything failed, and if so, which part.
Here's the awk script in its current state:
#! /usr/local/bin/awk -f
BEGIN {
return_code = 0
if ( length( username ) == 0 ){
return_code = 2
exit return_code
}
rows = 0
}
{
if ( $8 != sprintf("\"%s\",", username ) ) next
rows = rows+1
print $0
}
END {
if ( return_code > 0 ) exit return_code
if ( rows == 0 ) exit 3
}
The awk script has some custom value validation and exit codes. The return codes 1, 2 and 3 mean:
- Awk failed (for some reason related to awk)
- No username was specified for awk to parse for
- The username was specified, but no values were found
Test #1 (working properly)
An example execution (hiding the output from the awk script, since this question is related to return codes specifically):
$ sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log* 2>/dev/null | awk -v username="${USER}" -f ./parse-accountpoliocy.awk &>/dev/null
$ echo ${PIPESTATUS[@]}
0 0
You can see that ${PIPESTATUS[@]} shows that both sudo and awk were successful, which is expected, as I know I have sudo access, and the awk variable username was set and has log entries.
Test #2 (working properly)
Now if we change the awk variable username to an account that does not exist, then the awk script should exit with a return code of 3:
$ sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log* 2>/dev/null | awk -v username="fakeuser" -f ./parse-accountpoliocy.awk &>/dev/null
$ echo ${PIPESTATUS[@]}
0 3
Perfect!
Test #3 (Problem..)
If I execute the command above, but neglect to define the username awk variable, then the awk script should exit with a return code of 2
$ sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log* 2>/dev/null | awk -f ./parse-accountpoliocy.awk &>/dev/null
$ echo ${PIPESTATUS[@]}
141 2
As you can see, the awk script does return 2, but now for some reason, the sudo/zgrep returns 141, despite the fact that that part of the command wasn't altered at all... and this is the problem I’m running into.
I even tried to execute the command without hiding the output (of either STDOUT or STDERR), and the result was the same, but no error was displayed:
$ sudo -n zgrep -h AuthenticationAllowed /var/log/accountpolicy.log* | awk -f ./parse-accountpoliocy.awk
$ echo ${PIPESTATUS[@]}
141 2
Question
How can the exit code of the awk script change the exit code for the sudo/zgrep command stored within ${PIPESTATUS[@]}?
Environmental Information
- OSx Version: 10.11.6 (El Capitan)
- Bash Version: 4.4.12
- AWK Version: GNU Awk 4.1.4
rowsvariable asawkalready has theNRvariable bultin which counts the records (lines in this case).