System Administration
cancel
Showing results for 
Search instead for 
Did you mean: 

Background processes result code in HP-UX

SOLVED
Go to solution
Horia Chirculescu
Honored Contributor

Background processes result code in HP-UX

Hello,

I have this sh code:
#-----------------------------
cp -pr PROD/[a-g,A-G]* $DIR/oradata/PROD/ &
cp -pr PROD/[h-k,H-K]* $DIR/oradata/PROD/ &
cp -pr PROD/[m-t,M-T]* $DIR/oradata/PROD/ &
cp -pr PROD/[u-z,U-Z]* $DIR/oradata/PROD/

wait
#-----------------------------

How can I find out if some of the cp (any or all and which one) had a problem and exited with a non-zero status?


I have tryed

if [ $? != 0 ] ; then ....

afther wait

But I found out that $? is allways zero when waiting for more than one child.

Best regards,
Horia Chirculescu
Best regards from Romania,
Horia.
13 REPLIES
James R. Ferguson
Acclaimed Contributor
Solution

Re: Background processes result code in HP-UX

Hi Horia:

You need to capture in a variable the pid of each process as you start them. Then, 'wait()' for the process(es) by pid. When the 'wait()' is satisfied, you can test '$? to obtain the completed process's return code. By example:

# cat ./proc.sh
#!/usr/bin/sh
./proc_1 &
PID1=$!
./proc_2 &
PID2=$!
echo "...two processes started -- ${PID1} ${PID2}"
wait ${PID1}
echo "process-1 ${PID1} done with rc=$?"
wait ${PID2}
echo "process-2 ${PID2} done with rc=$?"

# cat ./proc_1
#!/usr/bin/sh
sleep 20
exit 1

# cat ./proc_2
#!/usr/bin/sh
sleep 10
exit 0

# ./proc.sh
...two processes started -- 14061 14062
process-1 14061 done with rc=1
process-2 14062 done with rc=0

...That is, you can do synchronous work; wait for all processes to terminate; and interrogate the return code of each process when it terminates.

Regards!

...JRF...
Horia Chirculescu
Honored Contributor

Re: Background processes result code in HP-UX

Hello, James

Glad to meet you.

Here it is my script based on your idea. Any comment may help.

#-----------------------------------------
mv PROD/log/PROD_* $DIR/oradata/PROD/log &
PID1=$!
cp -pr PROD/[a-g,A-G]* $DIR/oradata/PROD/ &
PID2=$!
cp -pr PROD/[h-k,H-K]* $DIR/oradata/PROD/ &
PID3=$!
cp -pr PROD/[m-t,M-T]* $DIR/oradata/PROD/ &
PID4=$!
cp -pr PROD/[u-z,U-Z]* $DIR/oradata/PROD/
rc5=$?

#Waiting for the background processes to finish
wait ${PID1}
rc1=$$?
wait ${PID2}
rc2=$?
wait ${PID3}
rc3=$?
wait ${PID4}
rc4=$?

if [ $rc1 != 0 ] or [ $rc2 != 0 ] or [ $rc3 != 0 ] or [ $rc4 != 0 ] or [ $rc5 != 0 ]
; then echo "Copy was not possible."

#-----------------------------------------


Best regards
Horia Chirculescu
Best regards from Romania,
Horia.
James R. Ferguson
Acclaimed Contributor

Re: Background processes result code in HP-UX

Hi (again) Horia:

Make sure to declare your interpreter at the head of the file:

#!/usr/bin/sh

...
rc1=$$?
...should be:
rc1=$?

Your 'if' statement needs to be:

if [ $rc1 != 0 -o $rc2 != 0 -o $rc3 != 0 -o $rc4 != 0 -0 $rc5 != 0 ]; then
echo "Copy was not possible."
fi

See the 'test(1)' manpages.

A better form would double-quote the variables to prevent syntax errors if they were undefined (empty). Enclosing the variable in curly braces is a good habit to develop. It avoids any ambiguity.

if [ "${rc1}" != 0 -o "${rc2}" != 0 -o "${rc3}" != 0 -o "${rc4}" != 0 -0 "${rc5}" != 0 ]; then
echo "Copy was not possible."
fi

Regards!

...JRF...


Dennis Handly
Acclaimed Contributor

Re: Background processes result code in HP-UX

>JRF: Your 'if' statement needs to be:
if [ $rc1 != 0 -o $rc2 != 0 -o $rc3 != 0 -o $rc4 != 0 -0 $rc5 != 0 ]; then

Since these are numeric values and not strings, it should be:
if [ $rc1 -ne 0 -o $rc2 -ne 0 -o $rc3 -ne 0 -o $rc4 -ne 0 -o $rc5 -ne 0 ]; then
Horia Chirculescu
Honored Contributor

Re: Background processes result code in HP-UX

Dennis,

James is right

[oltsnlo]:/root/Horia/Cluster # test "0" = 0
[oltsnlo]:/root/Horia/Cluster # echo $?
0
[oltsnlo]:/root/Horia/Cluster # test "123" = 123
[oltsnlo]:/root/Horia/Cluster # echo $?
0
[oltsnlo]:/root/Horia/Cluster # test 111 = 111
[oltsnlo]:/root/Horia/Cluster # echo $?
0
[oltsnlo]:/root/Horia/Cluster # test "111" = 123
[oltsnlo]:/root/Horia/Cluster # echo $?
1


So it seems that it does not matter on this shell (Posix shell).
Best regards from Romania,
Horia.
Dennis Handly
Acclaimed Contributor

Re: Background processes result code in HP-UX

>Chirculescu: James is right... So it seems that it does not matter on this shell (Posix shell).

There is a difference between strings and numeric values and their comparisons. There is a difference between something that works in some cases and something that always works. I wanted to make sure you used the correct syntax for comparing the exit status.
if [ $? = 00 ]; then
if [ $? -eq 00 ]; then

Horia Chirculescu
Honored Contributor

Re: Background processes result code in HP-UX

Dennis,

It is hard to make a script to "always work" as you suggest.

If I would change the current shell (Posix shell in this case) to be let's say Bourne shell or whatever other shell I do have installed (csh maybe), I do not expect that my script would work.

This is why I use at the beginning of the script the particular shell I use

#!/bin/sh

It was suggested also by James. This is not a "must" becouse someone could source the script to whatever shell he want/need and hope that things will go as expected.

Best regards,
Horia Chirculescu.
Best regards from Romania,
Horia.
Dennis Handly
Acclaimed Contributor

Re: Background processes result code in HP-UX

>It is hard to make a script to "always work" as you suggest.

Not scripts but numeric comparisons. I assume you know why "9 > 10" but "9 -lt 10".
James R. Ferguson
Acclaimed Contributor

Re: Background processes result code in HP-UX

HI (again) Horia:

> It is hard to make a script to "always work" as you suggest.

As Dennis correctly noted, "Not scripts but numeric comparisons.".

Dennis is right. I should have told you to use the '-ne' operator since a return code is an integer. The string comparison operator I used works because we are comparing equality, but it isn't good form.

I have always found the shell's use of '-eq', '-lt' and '-gt' for algebraic comparisons while reserving '=', '<' and '>' for string comparisons, to be counterintuitive. In Perl, the operators are just reversed (without the hyphen too). While it's a bit of a lame excuse, I do more Perl than shell :-)

See "Conditional Expressions" in:

http://docs.hp.com/en/B2355-60130/sh-posix.1.html

Regards!

...JRF...
Duncan Edmonstone
Honored Contributor

Re: Background processes result code in HP-UX

Just to add to the confusion... a word of warning on using "wait " in scripts...

if the command you are intending to wait for *exits* before you call wait, you will *not* get the return code of the process... so for shortlived processes, I tend not to trust wait, and always put some sort of shell wrapper around any background process where I can collect status information (into a file for example)

HTH

Duncan

HTH

Duncan
Horia Chirculescu
Honored Contributor

Re: Background processes result code in HP-UX

Thank you all for the replys.

I will close this thread as it it clear now.

Best regards,
Horia Chirculescu
Vianet Serv SRL.
Best regards from Romania,
Horia.
Horia Chirculescu
Honored Contributor

Re: Background processes result code in HP-UX

Thread closed.
Best regards from Romania,
Horia.
Dennis Handly
Acclaimed Contributor

Re: Background processes result code in HP-UX

>JRF: I have always found the shell's use of '-eq', '-lt' and '-gt' ..., to be counterintuitive.

If you are only doing numeric comparisons, then you can switch to C style:
if (( rc1 != 0 || rc2 != 0 || rc3 != 0 || rc4 != 0 || rc5 != 0 )); then

Or if you think these are boolean values:
if (( rc1 || rc2 || rc3 || rc4 || rc5 )); then