views:

1951

answers:

5

In a sort of try/catch form I want to execute a bash that doesn't stop if an error occurs.

The specific bash is:

#!/bin/sh

invoke-rc.d tomcat stop

rm -fr /var/webapps/
cp -R $WEBAPP /var/webapps/
invoke-rc.d tomcat start

I want to exec "invoke-rc.d tomcat stop" and even if Tomcat is not running, continue to execute the other bash commands.

+5  A: 

Try:

invoke-rc.d tomcat stop > /dev/null 2>&1 || true

A little background:

user@tower: # true
user@tower: # echo $?
0
user@tower: # false
user@tower: # echo $?
1

user@tower: # which true
/bin/true
user@tower: # which false
/bin/false

The real solution is looking at the tomcat init script to see how it knows if tomcat is running :) That way, you don't pester it needlessly.

See this post on the other suggestion to unset / set +e. While it would solve your immediate problem, you may find that you need the recently unset behavior in your own script, especially since you are copying files.

This is one of the biggest reasons why true and false were made, other than making Makefiles behave as expected in a variety of build environments.

Also, set +e is not entirely portable, i.e. some versions of Solaris (and even Dash) .. but I doubt that this is a concern for you.

Tim Post
I removed the paths of your code and the root user because somebody might think you need to be su. Hope you don't mind ;)
victor hugo
@victor hugo - Thanks. I edited this post a few times and failed to notice that I left the paths in tact :) I must be slightly brain dead today.
Tim Post
A: 

Try redirecting the standard error to a file ...something like 2> myerror.

Vaibhav
If seen something like command > /dev/null. Is it something like that? This will make the output of the command go to a file. But does also catch the error?
JorgeO
This does not recover from the error, it merely hides the cause.
Tim Post
+1  A: 

Use bash's set command to temporarily disable exit-on-nonzero behaviour.

set +e
invoke-rc.d tomcat stop
set -e
You should write a little explanation of your script. Just click 'edit'. BTW Welcome to SO
victor hugo
set {args} is not always portable. However, if you do:set +e || { code to cope with a brain dead shell}Its just fine for anything worth its salt in POSIX conformity.Universally, its much easier (and much more portable) to just use true / false.
Tim Post
+5  A: 

Disable the "exit immediately" option with set +e, run your command, then optionally re-enable it with set -e:

set +e
invoke-rc.d tomcat stop
set -e  # optional

See section 4.3.1 of the Bash manual for an explanation of the set builtin and all of its various options (of which there are many).

Adam Rosenfield
That just (often) creates a circular problem, as the parent script might actually want +e behavior. I know its sometimes silly to be so pedantic, but when it comes to dealing with init scripts, true / false are your friends.
Tim Post
+1  A: 

If invoke-rc.d tomcat stop is the only thing you want to protect against failing, maybe invoke-rc.d tomcat stop || true may do it? That should never have a non-zero exit status.

Vatine