Terminate initially if error found...

Hi,

I have written a shell script which is a combination of 5 scripts into one.
We have a Record Claim indicator in the scpt ($rc) with which we can come to an conclusion if the script failed to load the data or if the data loaded successfully.

Can any one please help me as to how to write a script which terminates if the $rc fails initially or in the middle.

Example.
Script1.sh
Script2.sh
Script3.sh
Script4.sh
Script5.sh

If Script1.sh has error, or data is not loaded, the script should terminate at this point and should not go to the Script2.sh to load the data.

Has anyone faced this issue before or have written a script which terminates at Script1.sh and does not proceed to next level.

Please advice.

Thanks

Well, exit 0 is true, so you can test with logic operators or $?, but make sure you catch errors and return not 0 if there is a problem. In critical unattended scripts, it is good to catch $? on everything down to binary code. Ecen on a pipeline, you cna subshell each command and check for error. Did you know sort errors out if it cannot write all its data?

Please show us how you run these scripts? Are you typing the commands at a keyboard? Are you using unix "cron"? Is there a wrapper script - if so, what does the script contain?

Script1.sh 
Script2.sh 
Script3.sh 
Script4.sh 
Script5.sh 

Ps. As DGPickett implies you can indeed cause a sub-Script to exit with a non-zero exit status (e.g. "exit 2")which you can check in a wrapper script. Test the value of the variable $? on the line immediately following the invocation of the sub-Script in a numeric comparison. This is good scripting technique and not at all unusual. Confine exit codes to simple and low numbers because no Shell will allow a non-numeric exit code and many Shells cannot deal with large numbers in exit codes.

Difficult to suggest suitable scripting without knowing the possible values of $rc and knowing whether the variable contains a number or a string.

Ps. It always helps to know what Operating System and version you have and what Shell you prefer.

Hi,
I have attached the script as an attachment.

Please advice as to how to write the script which will stop the subscript if errors found, without proceeding further to the next subscript.

Based on your original request, if you simply want your wrapper script to exit if a subscript exits with a non-0 status, then add set -e , as in:

Now based on your attachement, I would do something like:

(
  set -e
  Script1.sh
  Script2.sh
  Script3.sh
  Script4.sh
  Script5.sh
)

rc=$?
case ${rc} in
  0)
    echo 'Claim table load Successful'  
    mv /space/dbexport/data/cExport.csv /space/dbexport/archive/cExport-`date +%Y%m%d`.csv
    ;;
 
  2)
    echo 'Claims table load finished with warnings/errors--- Return Code=' $rc  
    mv /space/dbexport/data/cExport.csv /space/dbexport/archive/cExport-`date +%Y%m%d`.csv  
    ;;
 
  4)
    echo 'Claims table load failed--- Return Code=' $rc  
    ;;
esac

exit $rc

but this would treat the 5 sub-scripts as a single unit -- which may or may not be what you need.

Can you please explain to me as to what "sed -e" does here.

I dont want it to consider the whole sub-script as one. They are 5 different sub-scripts and each should run individually.

Appreciate any help or advice.

Thanks!

From the man bash (linux) manpage:set [--abefhkmnptuvxBCEHPT] [-o option] [arg ...]
set [+abefhkmnptuvxBCEHPT] [+o option] [arg ...]-e [INDENT]Exit immediately if a pipeline (which may consist of a single simple command), a subshell command enclosed in parentheses, or one of the commands executed as part of a command list enclosed by braces (see SHELL GRAMMAR above) exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or list except the command following the final && or , any command in a pipeline but the last, or if the command's return value is being inverted with !. A trap on ERR, if set, is executed before the shell exits. This option applies to the shell environment and each subshell envi- ronment separately (see COMMAND EXECUTION ENVIRONMENT above), and may cause subshells to exit before executing all the commands in the subshell.
[/INDENT]So the set -e causes the sub-shell to exit if any command exits with a non-zero status. Each sub-script is executed in order, the execution just stops when one fails.

You could have also done:

Script1.sh || Script2.sh || Script3.sh || Script4.sh || Script5.sh

rc=$?
.....

instead of the sub-shell. Up to you which implementation works best for you.

Now if you want to have per-script error processing, then you are going to have to do something like:

Script1.sh

rc=$?
case ${rc} in
  0) rc0script1stuff ;;
  2) rc2script1stuff ; exit ${rc} ;;
  4) rc4script1stuff ; exit ${rc} ;;
  *) echo Script1 has an undefined exit code - ${rc} ; exit ${rc} ;;
esac

Script2.sh

rc=$?
case ${rc} in
  0) rc0script2stuff ;;
  2) rc2script2stuff ; exit ${rc} ;;
  4) rc4script2stuff ; exit ${rc} ;;
  *) echo Script2 has an undefined exit code - ${rc} ; exit ${rc} ;;
esac

..... and so on .....

Of course, all the child scripts must know how to exit not zero on any sort of error, a recursive search for unexpected exits and unchecked conditions.

I tried with the pre-script error processing, with "sed -e". Looks like its working fine, but for what ever case (0 ,2, 4), it should send the e-mail to the user, stating the result.
But as per the script, its not sending e-mail for any failure, but the user is receiving the e-mail for any success.

Can you please look at the sub-script attached to this e-mail and let me know as to where i am going wrong.

No, shell command set -e, nothing to do with sed, the stream editor.

I got rid of set -e command.

Now i am facing a new issue.
When i execute the shell script, it just shows me blank with no progress.

-bash-3.00$ ./sqlldrclaims_backup_new.sh
Password:
SQL*Loader: Release 11.2.0.1.0 - Production on Tue Jan 18 10:26:39 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.

When i do "ps -ef" i see this

zx01324 25166 25150   0 10:12:25 pts/1       0:00 sqlldr zx01182 control=/space/dbexport/PHR/control/claims.ctl log=/space/dbexpo

Can anyone explain to me as to what's going on, as it used to load the data, but now,, its runs at the background.

http://www.unix.com/shell-programming-scripting/147421-sending-email-multiple-files-5.html
In you previous threads on this script from a couple of months ago I don't think we found out what Shell you were using.

Anyway, one of your problems may be the "set -e".

         -e   Execute the ERR trap, if set, and exit if a command has a
                nonzero exit status, and is not part of the compound list
                following a if, until, or while keyword, and is not part of
                an AND or OR list, and is not a pipeline preceded by the !
                reserved word.  This mode is disabled while reading
                profiles.

Good idea to put a line in after saving $rc to display the value. This will tell you if the line is ever executed when the preceding command returns a non-zero exist status.

rc=$?
echo "The value of rc = $rc"

You can set -ex and get a progress report as child processes are started. However, if there is information to catch in the return code, you need to capture $? in another variable, IMMMEDIATELY, before it is overwritten by your error handling code.

But that is your choice, in terms of error handling architecture. The child script could log everything and just return 0 or 1, so when testing a child, you do not need the parent or a hand coded echo $? to see the result (and you might overlook that in a quick test). Logging should be clear, so it is good to have the parent log just say 'parent started at this time, started child at this time with these arguments, child can write log location, child ended good or bad at this time, parent ended at this time. This way, clutter can be logged down at the leaf level, and in some case rejects or errors are potentially large enough to go in a specific separate file, not the main log, but with the side log path and its stats in the main log. If you reuse the same log path, there should be internal start/end headers and code to prevent two runs at once.

You, too, deserve good error checking, handling, logging. Think of it as a real product, just like processed data. When x runs, it owes me an output file and a log of happy ending or a log of why not, all the time, 100%, unity, 1.0 probability!

Methyl,

I am sorry for not replying back to you as to what Shell i am using.

The answer is :

Its "bash"

-bash-3.00$ echo $0
-bash

While trying to find what you main command is trying to do, I mostly come across various versions of your script on various boards. For example:
Getting this error message 'LRM-00112: multiple values not allowed for parameter 'log' - Toolbox for IT Groups
This one reminded me that there is nothing in the script you posted today to set the Oracle environment. Also "$to" is not defined.

Are we seeing the whole script? Sometimes the cause of a script problem is many lines from the effect.

Do you get some positive feedback from the main command sequence which proves that it works?

Same basic process in sh and ksh, even csh.

Well i think the issue is resolved here.

Sorry for replying back so late, but i would like to thanks each one of you for your help and support, in making this work.