Blog

03/06/2019

Bash Find out the exit codes of all piped commands



How do I get exit status of process that’s piped to another (for e.g. ‘netstat -tulpn | grep nginx‘) on a Linux or Unix-like system using a bash shell?

A shell pipe is a way to connect the output of one program to the input of another program without any temporary file. The syntax is:[donotprint][/donotprint]

command1 | command2 | commandN

OR

command1 | filter_data_command > output

OR

get_data_command | verify_data_command | process_data_command | format_data_command > output.data.file

How to use pipes to connect programs

Use the vertical bar (|) between two commands. In this example, send netstat command output to grep command i.e. find out if nginx process exits or not in the system:
# netstat -tulpn | grep nginx
Sample outputs:

Fig.01: Find the exit status of pipe command

How to get exit status of process that’s piped to another

The syntax is as follows to get exit codes of all piped commands:

command1 | command2 
echo "${PIPESTATUS[@]}"

OR

command1 | command2 
echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}"

PIPESTATUS is an array variable containing a list of exit status values from the processes in the most-recently-executed foreground pipeline. Try the following commands:

netstat -tulpn | grep nginx
echo "${PIPESTATUS[@]}"
 
true | true
echo "The exit status of first command ${PIPESTATUS[0]}, and the second command ${PIPESTATUS[1]}"
 
true | false
echo "The exit status of first command ${PIPESTATUS[0]}, and the second command ${PIPESTATUS[1]}"
 
false | false | true 
echo "The exit status of first command ${PIPESTATUS[0]}, second command ${PIPESTATUS[1]}, and third command ${PIPESTATUS[2]}"

Sample outputs:

Fig.02: Use the PIPESTATUS array to get the exit status of each element of the pipeline (click to enlarge)

Putting it all together

Here is a sample script that use ${PIPESTATUS[0]} to find out the exit status of mysqldump command in order to notify user on screen about database backup status:

#!/bin/bash
### Purpose: mysql.backup.sh : Backup database ###
### Author: SXI ADMIN <https://sxi.io>, under GPL v2.x+ or above. ###
### Change as per your needs ###
set -eo pipefail
MUSER='USERNAME-here'
MPASS='PASSWORD-here'
MHOST='10.0.3.100'  
DEST="/nfs42/backups/mysql"
NOWFORMAT="%m_%d_%Y_%H_%M_%S%P"
MYSQL="/usr/bin/mysql"
MYSQLDUMP="/usr/bin/mysqldump"
MKDIR="/bin/mkdir"
RM="/bin/rm"
GZIP="/bin/gzip"
DATE="/bin/date"
SED="/bin/sed"
 
# Failsafe? Create dir #
[  ! -d "$DEST" ] && $MKDIR -p "$DEST"
 
# Filter db names
DBS="$($MYSQL -u $MUSER -h $MHOST -p$MPASS -Bse 'show databases')"
DBS="$($SED -e 's/performance_schema//' -e 's/information_schema//' <<<$DBS)"
 
# Okay, let us go
for db in $DBS
do
                tTime=$(date +"${NOWFORMAT}")
                FILE="$DEST/${db}.${tTime}.gz"
                $MYSQLDUMP -u $MUSER -h $MHOST -p$MPASS $db | $GZIP -9 > $FILE
				if [ ${PIPESTATUS[0]} -ne "0" ];
				then
				    echo "The command $MYSQLDUMP failed with error code ${PIPESTATUS[0]}."
				    exit 1
				else
				    echo "Database $db dump successfully."
				fi
done

A note about zsh user

Use the array called pipestatus as follows:

true | true
echo "${pipestatus[1]} ${pipestatus[2]}"

Outputs:

0 0

Conclusion – Finding exit codes of all piped commands

The exit status of a pipeline is the exit status of the last command in the pipeline, unless the pipefail option is enabled too. Just add the following at the top of your bash shell script:
set -eo pipefail
To pipe output and capture exit status in Bash shell use:

date | grep 2018
echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}"
false | true
echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}"

For more info see:

Posted by: SXI ADMIN

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.

14/08/2019

How to KVM, QEMU start or stop virtual machine from command line (CLI)

KVM or Kernel Based Virtual Machine is a popular virtualization technology. It allows you to run virtual guest machines over a host machine. To start...
14/08/2019

How to Docker backup Saving and restoring your volumes

Running a Docker volume backup First, we spin up a temporary container, and we mount the backup folder and the target Docker volume to this container....
12/08/2019

How to Start and Enable Firewalld on CentOS 7

In this article, we discuss how to start and enable firewalld. It is highly recommended that you have a firewall protecting your server.Pre-Flight CheckThese...