help-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] Terminate calling bash script upon receiving non zero re


From: Peng Yu
Subject: Re: [Help-bash] Terminate calling bash script upon receiving non zero return status (and possibly terminate calling script recursively)
Date: Mon, 23 Apr 2012 10:20:25 -0500

On Mon, Apr 23, 2012 at 10:05 AM, Greg Wooledge <address@hidden> wrote:
> On Mon, Apr 23, 2012 at 09:41:05AM -0500, Peng Yu wrote:
>> I'm looking for a feature that can terminate the calling bash script
>> if the called program return non zero status. But I don't find such a
>> feature.
>
> What you want is a magical fairy-tale version of "set -e" which actually
> reads your mind and works the way you expect.
>
> As you have concluded, there is no such thing.  There is only the real
> set -e, which fails half the time and is confusing all of the time.

I wasn't aware of '-e' before. But it seems to be what I am looking
for. See the example below.

I don't get when it is going to fail and when it is confusing. Would
you please let me know what you mean here?

~/linux/test/gnu/bash/man/shell_builtin_commands/set/-e$ ./main.sh
~/linux/test/gnu/bash/man/shell_builtin_commands/set/-e$ cat.sh *
==> main.sh <==
#!/usr/bin/env bash

set -e
./main1.sh
echo $?
echo "Hello World!"

==> main1.sh <==
#!/usr/bin/env bash

set -e
./main2.sh
echo 'In main1.sh'


==> main2.sh <==
#!/usr/bin/env bash

exit 1



>> I see that && is useful in the following. If prog1 is not returning
>> zero, prog2 will not be called.
>>
>> prog1 && prog2
>>
>> But this is not convenient if I need to calls many programs.
>>
>> prog1 && prog2 ....  && prog_n
>
> Is every one of them REALLY so critical to your script's execution that
> you must abort if any one of them fails?  In most scripts there are
> only a handful of places that you really need to error check.
>
> #!/bin/bash
> # phony example script - rotate a log file
> die() { echo "$1" >&2; exit 1; }
>
> cd /my/log/directory || die "couldn't cd to the log directory"
> rm -f *.old *.old.gz
> mv mylogfile mylogfile.old 2>/dev/null
> mydaemon --open-a-new-log-file
> chmod 600 mylogfile
> nohup gzip -9 mylogfile.old >/dev/null 2>&1 &
>
> In this script, there is only one critical command -- the cd.  If that
> fails, then our rm would occur in the wrong place... it would be an
> absolute disaster.  We don't want to do ANYTHING if we can't cd to the
> log directory, so we check the cd for errors, and abort.
>
> rm -f doesn't return failure if the file doesn't exist.  That's the point
> of using the -f flag.  If the file's not there, we move on.
>
> I suppressed stderr from the mv because I don't want to hear any moaning
> if the current log file (that we're attempting to rotate) doesn't exist.
> If it's not there, we simply move on.  Yes, I could check for the file
> with a test or [[ or [ command, but why bother?  If mv does nothing, then
> it does nothing.
>
> Then we tell mydaemon to open a new log file.  This is daemon-specific.
> I also don't care if it fails.  It might fail if the daemon's not running,
> for example.  In that case, some OTHER script will be responsible for
> restarting it or notifying someone or whatever.  Not my problem.  I'm just
> rotating a log file, which means I need the daemon to stop writing to it.
> If the daemon isn't running, then it's not writing to it -- no problem!
>
> (This is also where a made-up example falls a bit short.  Maybe in
> real life I'd retry a few times, or notify someone in this script.
> Maybe not.  There are so many different situations, and there IS NO
> GENERAL FORMULA for how to handle them all.  Each shell script is unique,
> like a snowflake.  Or more like a bullet wound.  Shell script code is
> short, brutal, direct, and dirty.  It is not reusable.)
>
> If the chmod fails, that probably means the previous command also failed;
> that is, there is no current log file.  Here I didn't suppress errors.
> If there's no current log file to chmod, then let it notify me.  Maybe in
> a different log rotate script I'd suppress errors.  Or maybe I'd abort if
> the daemon kick failed.  Or maybe I'd sleep until the file exists, or until
> it's been 10 minutes, whichever comes first.  Etc.
>
> Then I compress the old log file, in the background, suppressing errors.
> If there's no old log file to compress, that error message will be
> discarded.  Out of sight, out of mind.  Since it's a background job, it
> will *always* return status 0 (unless I wait for it and retrieve its
> actual exit status, but if I were going to do that, I wouldn't run it in
> the background in the first place).
>
> So, we have a script with 6 commands in it, and we only error-checked one
> of them.  Not all 6.  And we didn't use set -e to do it.



-- 
Regards,
Peng



reply via email to

[Prev in Thread] Current Thread [Next in Thread]