[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