Thursday, 5 February 2026

pipe status


[root@oel01db ~]# echo hello

hello

[root@oel01db ~]#

[root@oel01db ~]# echo $?

0

[root@oel01db ~]#


[root@oel01db ~]# echo hello | grep hi

[root@oel01db ~]#

[root@oel01db ~]# echo $?

1

[root@oel01db ~]#


$? always stores the exit status of the very last command executed in the foreground.

Here echo hello is succeeded , where as grep hi failed, hence the exit code 1

## The Exit Code Logic

In Linux, every command returns an exit status (stored in the $? variable) to tell the system how it went. For grep:

  • 0 (Success): A match was found.

  • 1 (Failure to match): The command ran perfectly, but the pattern ("hi") was not found in the input ("hello").

  • 2 (Error): There was a syntax error or the file doesn't exist.

Check man page for the exit code for a command.

Example 2

[root@oel01db ~]# cat non-existing-file
cat: non-existing-file: No such file or directory
[root@oel01db ~]#
[root@oel01db ~]# echo $?
1
[root@oel01db ~]#
[root@oel01db ~]# cat non-existing-file | tr , :
cat: non-existing-file: No such file or directory
[root@oel01db ~]#
[root@oel01db ~]# echo $?
0
[root@oel01db ~]#

Why we got exit code 0 ?

## The Breakdown

  1. cat non-existing-file: This command failed because the file doesn't exist. Its internal exit code was 1.

  2. | (The Pipe): This passed the (empty) output of cat over to the next command.

  3. tr , :: This command received nothing from the pipe, performed "nothing" successfully, and finished. Because it didn't encounter a system error, it exited with 0.

Since tr was the last command in the pipeline, the shell updated $? to 0.

## How to see the "Real" failure

If you want to catch errors that happen earlier in the pipe, you have two main options:

Option 1: Use ${PIPESTATUS} (Bash/Zsh)

PIPESTATUS is a built-in array variable in Bash that stores the exit status (return codes) of every single command in the most recently executed foreground pipeline.

[root@oel01db ~]# cat non-existing-file | tr , :

cat: non-existing-file: No such file or directory
[root@oel01db ~]# echo "${PIPESTATUS[@]}"
1 0
  • 1 is the failure from cat.

  • 0 is the success from tr.


[root@oel01db ~]# cat non-existing-file | tr , :
cat: non-existing-file: No such file or directory
[root@oel01db ~]#
[root@oel01db ~]# echo "${PIPESTATUS[1]}"
0
[root@oel01db ~]#

${PIPESTATUS[0]} = Exit code of command1

${PIPESTATUS[1]} = Exit code of command2

${PIPESTATUS[2]} = Exit code of command3

Option 2: Use set -o pipefail

This is a safer way to write scripts. If you enable this, the entire pipeline will return a non-zero exit code if any command in the chain fails.


[root@oel01db ~]# set -o pipefail
[root@oel01db ~]# cat non-existing-file | tr , :
cat: non-existing-file: No such file or directory
[root@oel01db ~]# echo $?
1
[root@oel01db ~]#

No comments:

Post a Comment

JFrog Artifactory - How to install

JFrog Artifactory OSS Installation Guide CentOS 9 + PostgreSQL 17 This guide provides a structured workflow to install JFrog Artifactory OSS...