Exit code from piping in unix shell script

Hi ,

I have following code in my shell script :

"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p1.stx" "${TS_LOGS}/tranfrmr_p1.err" | (
"$TS_BIN/cusparse" "${TS_SETTINGS}/cusparse_p2.stx" "${TS_LOGS}/cusparse_p2.err" | (
"$TS_BIN/tsqsort" "${TS_SETTINGS}/srtforpm_p3.stx" "${TS_LOGS}/srtforpm_p3.err" | (
"$TS_BIN/uspmatch" "${TS_SETTINGS}/pmatch_p4.stx" "${TS_LOGS}/pmatch_p4.err" | (
"$TS_BIN/winkey" "${TS_SETTINGS}/winkey_p5.stx" "${TS_LOGS}/winkey_p5.err" | (
"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p6.stx" "${TS_LOGS}/tranfrmr_p6.err" | (
"$TS_BIN/tsqsort" "${TS_SETTINGS}/srtforrl_p7.stx" "${TS_LOGS}/srtforrl_p7.err" | (
"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p8.stx" "${TS_LOGS}/tranfrmr_p8.err")))))))

"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p9.stx" "${TS_LOGS}/tranfrmr_p9.err"
"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p10.stx" "${TS_LOGS}/tranfrmr_p10.err"
"$TS_BIN/rellink" "${TS_SETTINGS}/rellinkref_p11.stx" "${TS_LOGS}/rellinkref_p11.err"
"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p12.stx" "${TS_LOGS}/tranfrmr_p12.err" | (
"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p13.stx" "${TS_LOGS}/tranfrmr_p13.err")

"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p14.stx" "${TS_LOGS}/tranfrmr_p14.err"
"$TS_BIN/tsqsort" "${TS_SETTINGS}/srtforrl_p15.stx" "${TS_LOGS}/srtforrl_p15.err"

I want to capture the status code for each each command.
Suppose my below process fails and return status code is non zero

"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p6.stx" "${TS_LOGS}/tranfrmr_p6.err" 

than successor commands shouldn't get executed and script should get exited with non zero return status code.

Can anybody help me on that..

What Shell is this?
What is the purpose of the pipes and parentheses on some (but not all) of the lines? I've never seen a construct like this.

Hi,

This is a bash shell .
$TS_BIN/tranfrmr is script and ${TS_SETTINGS}/tranfrmr_p6.stx is our setting file stored in setting directory where we describe the input and output file
and "${TS_LOGS}/tranfrmr_p6.err" is the error file stored in log directory

When below process runs

"$TS_BIN/tranfrmr" "${TS_SETTINGS}/tranfrmr_p6.stx" "${TS_LOGS}/tranfrmr_p6.err"

the output file generated by above command will be input file for the sucessor command i.e

"$TS_BIN/tsqsort" "${TS_SETTINGS}/srtforrl_p7.stx" "${TS_LOGS}/srtforrl_p7.err"

and so on...

Does it need the pipeline at all?

Are you looking to detect an error exit status from each script, or to processes the ".err" files somehow?

Yes it need the pipeline ,because it is making our process faster,

We are basically looking for error exit status after each command . Actually when we are running the script our job is not capturing the failed exit status code after each command. while running whole of the process and it is giving status exit code 0

For example I have changed the setting file '

tranfrmr_p6.stx' and there is some syntax error or suppose i have changed the input file name in the file
than process should get exited with error code,but successor get run.

Please find the snapshot shot of log when the process is running .

In above case STEP :P6 is not able to process the input file so it skipped and moved the next sucessor process
STEP : p7_srtforrl

Also please find the content of the setting file (tranfrmr_p6.stx) .
Please find top and last content as it is a very long xml code

Are you passing any data at all down any of the pipelines?
Sorry to labour this point but it would be so much easier to check for errors at each stage if there was no pipeline.

> echo $PIPESTATUS
0

> ls -al | bogus_command
bash: bogus_command: command not found
> echo ${PIPESTATUS[1]}
127

PIPESTATUS is an array, each element of the array has the reutrn code for the corresponding pipe.

FWIW - your code is truly unmaintainable. If we had production code like that here we would absolutely require it to be refactored.

1 Like

Each time there is an opening parenthesis, I expect a new Sub-Shell to start. I just can't see how the code works unless there is nothing on any of the pipelines. Others may differ.

Hi Jim,

I'm using below code to capture return status of each pipe command in a file.

echo "${PIPESTATUS[1]} ${PIPESTATUS[2]} ${PIPESTATUS[3]} ${PIPESTATUS[4]} ${PIPESTATUS[5]} ${PIPESTATUS[6]} ${PIPESTATUS[7]} ${PIPESTATUS[8]}" > status

But the file contains 8 blank spaces

each array contains 1 blank space.