[GRASS-user] Re: Detect failure during batch job execution
Ivan Shmakov
ivan at theory.asu.ru
Wed Dec 12 22:57:41 EST 2007
>>>>> Hamish <hamish_b at yahoo.com> writes:
>>> Is there a way to detect whether an operation has succeeded or
>>> failed?
> Yes. The program will exit with an "exit code". For GRASS modules
> this will be "0" on success and "1" on fail.
More general convention is to use zero exit code for success and
a non-zero one for failure.
> I am not sure what a Seg-fault or other abnormal termination returns.
When program was terminated by a signal, the "$?" value will be
128 + SIGNAL, where SIGNAL is the signal number. You may check
$ kill -l for the signal numbers on your system.
$ bash -c 'kill -HUP $$' ; echo $?
Hangup
129
$ kill -l | grep HUP
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
$
Note that you can't distinguish between the ``normal'' and the
``signal-caused'' termination of the program if it uses exit
codes greater than 128.
> you can test the exit code for the last command from the Bash prompt
> with "$?".
> For example:
> g.module
> echo $?
> g.module
> RESULT=$?
> if [ $RESULT -ne 0 ] ; then
> echo "it exited with an error"
> fi
Or, otherwise (not saving the RESULT):
if ! g.module ; then
echo "it exited with an error"
fi
>>> Or whether a vector layer exists or not?
>> I am also interested into a solution on that.
> g.findfile element=vector file=mapname
> this will return various info about the map. You can set shell
> variables with it directly: eval `g.findfile element=vector
> file=roads` echo "$fullname"
> also the g.findfile return code is dependent on if the file was
> found or not.
I didn't know about `g.findfile'. Thanks!
> MAPNAME=roads
> if [ `g.findfile element=vector file="$MAPNAME"` -eq 0 ] ; then
> d.vect $MAPNAME
> fi
The backquotes (`COMMAND`) won't return you the exit code. Did
you mean ``[ -n `g.findfile ...` ]''?
> same as
> eval `g.findfile element=vector file="$MAPNAME"`
Not quite. This command seems to create (modify) some shell
variables, while the former one leaves the shell variables
untouched.
> if [ -n "$name" ] ; then
> d.vect $MAPNAME
It's better to always quote variable references, unless there's
a good reason not to. Thus:
d.vect "$MAPNAME"
> fi
One could probably write a function for it, e. g.:
probe () {
local element="$1" file="$2"
g.findfile element="$element" file="$file" > /dev/null 2>&1
}
if probe vector "$MAPNAME"; then
d.vect "$MAPNAME"
fi
>> I have been saving log to file using command > grass.log 2>&1
>> But this doensn't say anything about the result of the operation...
> If it exits with an error there will be "ERROR: ...." or a
> "Segmentation Fault" text. No output generally means everything was
> ok. Note some modules may successfully exit haven written 0
> features, e.g. v.extract where="x != x".
One may use time(1) to get the exit code as well:
$ time true
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+173minor)pagefaults 0swaps
$ time false
Command exited with non-zero status 1
0.01user 0.00system 0:00.00elapsed 250%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+174minor)pagefaults 0swaps
$
Beware that the time(8) may be hidden by a shell (e. g., Bash)
builtin with the same name! In Bash, e. g., one may use the
`command' command. Compare:
bash$ time false
real 0m0.000s
user 0m0.000s
sys 0m0.000s
bash$ command time false
Command exited with non-zero status 1
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+173minor)pagefaults 0swaps
bash$
(And knowing the time of execution of your script may be quite
useful, anyway.)
More information about the grass-user
mailing list