0

I am trying to understand how error catching works when piped to awk in a bash script. I have a bash script with :

#!/bin/bash
set -e 
echo "hello"
OUTPUT=`ls /root/* | awk '{print $0}'`  
echo "world"

When I run this as a non-privileged user, the output is

hello
ls: cannot access /root/*: Permission denied
world

despite the fact that set -e should cause my script to end if any error occurs. The line echo "world" should not be executed because the script does generate an error.

Now if I replace the awk statement with grep poo, the script exits as expected.

QUESTION: What is awk doing that manages to hide the errors from bash?

irritable_phd_syndrome
  • 4,631
  • 3
  • 32
  • 60
  • 1
    `set -e` does not work the way you think it does. It **absolutely does not** promise to make all errors fatal. See the exercises below the allegory in [BashFAQ #105](http://mywiki.wooledge.org/BashFAQ/105) (though reading the allegory may have value too, if you're not allergic to walls of text; it provides a fairly good explanation of how we got here, and *why* `set -e` [has mutually-incompatible implementations](https://www.in-ulm.de/~mascheck/various/set-e/) between different POSIX-family shells). – Charles Duffy Jul 13 '18 at 15:36
  • From the bash documentation: The shell does not exit if the command that fails is . . . any command in a pipeline but the last https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html – slowko Jul 13 '18 at 15:36
  • 1
    That said, see `set -o pipefail` to make a failure at any point in a pipeline fatal -- but, bigger picture, I strongly suggest reconsidering your use of `set -e`. – Charles Duffy Jul 13 '18 at 15:37

1 Answers1

1

This is completely by definition; the output status of a pipeline is the exit status of the last command in the pipeline.

You can trap this specific error in Awk explicitly:

ls /root/* | awk 'BEGIN {x=1} {x=0; print $NF } END { exit x }'

This causes Awk to set its exit status to reflect whether it received any input at all. This is similar to the grep behavior you discovered (report success if any matches were found).

tripleee
  • 175,061
  • 34
  • 275
  • 318