0

I have something like this:

while read line
do command1 $line | awk -v l="$line" '
    ...
    ... awk program here doing something ...
    ...
    '
done < inputfile.txt

Now, command1 will have three possible EXIT code statuses (0,1,2), and depending on which one occures, processing in awk program will be different. So, EXIT code serves the purpose of a logic in awk program.

My problem is, I don't know how to pass that EXIT code from command1 to my awk program.

I thought maybe there is a way of passing that EXIT code as a var, along with that line:

-v l="$line" -v l="$EXITCODE", but did not find the way of doing it.

After exiting from while do done loop, I still need access to ${PIPESTATUS[0]} (original exit status of a command1 command) variable, as I am doing some more stuff after.

ADDITION (LOGIC CHANGED)

while read line
do
    stdout=$(command $line);

    case $? in
        0 )
            # need to call awk program
            awk -v l="$line" -v stdout="$stdout" -f horsepower
            ;;
        1 )
            # no need to call awk program here..
            ;;
        2 )
            # no need to call awk program here..
            ;;
            ;;
        *)
            # something unimportant

    esac
done < inputfile.txt

So as you can see, I changed a logic a bit, so now I am doing my EXIT status code logic outside of awk program (now I made it as a separate program in its own file called horsepower), and need only to call it in case 0), to do processing on stdout output generated from previous command.

horsepower has few lines like:

#! /bin/awk -f

/some regex/ { some action }

, and based on what it finds it acts appropriately. But how to make it now act on that stdout?

branquito
  • 3,864
  • 5
  • 35
  • 60
  • See [this answer](http://stackoverflow.com/questions/962255/how-to-store-standard-error-in-a-variable-in-a-bash-script) – anubhava Jul 05 '14 at 13:51
  • I redefined the question, to avoid confusion with `stderr`, so I need to pass EXIT code of a `command1` to next command in a pipeline. – branquito Jul 05 '14 at 14:07
  • 1
    `command1` and `awk` will run simultaneously, so in general you can't depend on the exit status of `command1` being available yet at any point in the execution of the `awk` command. – chepner Jul 05 '14 at 14:44

1 Answers1

3

Don't Use PIPESTATUS Array

You can use the Bash PIPESTATUS array to capture the exit status of the last foreground pipeline. The trick is knowing which array element you need. However, you can't capture the exit status of the current pipeline this way. For example:

$ false | echo "${PIPESTATUS[0]}"
0

The first time you run this, the exit status will be 0. However, subsequent runs will return 1, because they're showing the status of the previous command.

Use Separate Commands

You'd be much better off using $? to display the exit status of the previous command. However, that will preclude using a pipeline. You will need to split your commands, perhaps storing your standard output in a variable that you can then feed to the next command. You can also feed the exit status of the last command into awk in the same way.

Since you only posted pseudo-code, consider this example:

$ stdout=$(grep root /etc/passwd); \
  awk -v status=$? \
      -v stdout="$stdout" \
  'BEGIN {printf "Status: %s\nVariable: %s\n", status, stdout}'
Status: 0
Variable: root:x:0:0:root,,,:/root:/bin/bash

Note the semicolon separating the commands. You wouldn't necessarily need the semicolon inside a script, but it allows you to cut and paste the example as a one-liner with separate commands.

The output of your command is stored in stdout, and the exit status is stored in $?. Both are declared as variables to awk, and available within your awk script.

Updated to Take Standard Input from Variable

The OP updated the original question, and now wants standard input to come from the data stored in the stdout variable that is storing the results of the command. This can be done with a here-string. The case statement in the updated question can be modified like so:

while read line; do
    stdout=$(command $line)
    case $? in
        0) awk -v l="$line" -f horsepower <<< "$stdout" ;;
        # other cases, as needed
    esac
done

In this example, the the stdout variable captures standard output from the command stored in line, and then reuses the variable as standard input to the awk script named "horsepower." There are a number of ways this sort of command evaluation can break, but this will work for the OP's use case as currently posted.

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
  • How would I than do processing on `stdout` variable from within `awk`, for example I have in my `awk` program - `/regex/ { action }`, and it was acting upon output of previous command piped into `awk`, so `awk` has been fed from `stdin`. – branquito Jul 05 '14 at 14:55
  • Please look at my addition part. – branquito Jul 05 '14 at 15:14
  • I tried similar, but instead of `here-string`, using `<(cat "$stdout")`. Could you explain why this was failing? – branquito Jul 05 '14 at 19:33
  • 1
    `< <(echo "$stdout")` should work, but *cat* needs a file or input stream. – Todd A. Jacobs Jul 05 '14 at 20:39