I tried learning how to write a bash script to have my own script to start and stop a Tomcat Server, and I can't seem to find what is causing the error in this script. I've double checked my if and fi statements to make sure they match, but still have no idea what is wrong.
EDIT:
Here is the exact error message
line 87: syntax error: unexpected end of file
Here is the script:
#!/bin/bash
#Returns the process id of the Tomcat server if currently running
function tomcat_pid {
local pid=0
local temp=$(ps x | grep "$CATALINA_HOME" | grep -v grep | cut -d ' ' -f 1)
if [ -n "$temp" ]; then
pid=$temp
fi
echo "$pid"
}#tomcat_pid
#Checks the status of the Tomcat Server
function tomcat_status {
local retval="Tomcat Server is not currently running"
local pid
pid=$(tomcat_pid)
if [ "$pid" -gt 0 ]; then
retval="Tomcat Server is running at pid: $pid"
fi
echo "$retval"
}#tomcat_status
#Starts the Tomcat Server
function tomcat_start {
local pid
pid=$(tomcat_pid)
if [ "$pid" -gt 0 ]; then
echo "Tomcat Server already running at pid: $pid"
else
echo "Starting Tomcat Server"
"$CATALINA_HOME/bin/startup.sh"
fi
}#tomcat_start
#Stops the Tomcat Server
function tomcat_stop {
local pid
pid=$(tomcat_pid)
if [ "$pid" -gt 0 ]; then
echo "Shutting down Tomcat Server"
"$CATALINA_HOME/bin/shutdown.sh"
else
echo "Tomcat Server is not currently running"
fi
}#tomcat_stop
#Restarts the Tomcat Server
function tomcat_restart {
local pid
pid=$(tomcat_pid)
if [ "$pid" -gt 0 ]; then
echo "Restarting the Tomcat Server"
"$CATALINA_HOME/bin/shutdown.sh"
sleep 5s
"$CATALINA_HOME/bin/start.sh"
else
echo "Starting the Tomcat Server"
"$CATALINA_HOME/bin/startup.sh"
fi
}#tomcat_restart
if [ -n "$1" ]; then
if [ "$1" = 'restart' ]; then
tomcat_restart
#tomcat start - Starts the Tomcat Server
elif [ "$1" = 'start' ]; then
tomcat_start
#tomcat shutdown - Shuts down the Tomcat Server
elif [ "$1" = 'shutdown' ]; then
tomcat_stop
#tomcat status - Checks the status of the tomcat server
elif [ "$1" = 'status' ]; then
tomcat_status
else
echo "Please use correct options"
fi
else
echo "Please use correct options"
fi
See man bash, in other words bash(1), Section SHELL GAMMAR
{ list; }
list is simply executed in the current shell environment. list must be terminated with a newline or semi‐
colon. This is known as a group command. The return status is the exit status of list. Note that unlike
the metacharacters ( and ), { and } are reserved words and must occur where a reserved word is permitted to
be recognized. Since they do not cause a word break, they must be separated from list by whitespace or
another shell metacharacter.
The last sentence points at your problem.
Related
Following script:
#Tomcat status
tc_status () {
ps aux | grep myapp123 | wc -l
}
#shutdown, if tomcat
if [ $(tc_status) -gt 0 ]; then
echo "Stopping Tomcat "; /home/user/shutdown.sh myapp123 > /dev/null 2>&1;
if [ $(tc_status) -eq 0 ]; then
echo "OK!"
fi
fi
#some other code
#startup
echo "Starting Tomcat...";
/home/user/startup.sh myapp123 > /dev/null 2>&1;
if [ $(tc_status) -gt 0 ]; then
echo "OK!";
fi
The above code first checks whether Tomcat is still running. If so, then it will be stopped, if not, further lines of code will be executed.
Finally the Tomcat is started. If it is running, there is an "OK" message.
The problem at this point is that the status is not 100% meaningful, especially when starting. Because the Tomcat process is running, but Tomcat usually takes several seconds or minutes until it is actually up.
How can I make sure that the Tomcat is actually DOWN and UP?
If your distro supports it, I recommend you to put your services under systemd. That way you can monitor it using the "service" command. It isn't hard to do it.
I know that this doesn't directly answers your question, but it'll give way more control over what's running and what isn't.
The unreliability of your script does not depend on the startup time of Tomcat, but on the fact that:
ps aux | grep app123 | wc -l
is unreliable: it matches also the grep app123 command (although this is subject to a race condition between ps and grep). On the other hand app123 is not a valid argument for the startup.sh script. The usage is:
startup.sh [ -config {pathname} ] [ -nonaming ] [ -generateCode [ {pathname} ] ] [ -useGeneratedCode ]
To reliably check if Tomcat is running, you should use a pidfile, which will be created at the location pointed by the CATALINA_PID environment variable.
So your script should look like:
# Be sure to have permissions to create this file
export CATALINA_PID=/run/tomcat.pid
# Tomcat status
tc_status () {
[ -f $CATALINA_PID ] && kill -0 $(<$CATALINA_PID)
}
#shutdown, if tomcat
if [ $(tc_status) -gt 0 ]; then
echo "Stopping Tomcat ";
/home/user/shutdown.sh >/dev/null 2>&1;
if [ $(tc_status) -eq 0 ]; then echo "OK!"; fi
fi
#some other code
#startup
echo "Starting Tomcat...";
/home/user/startup.sh >/dev/null 2>&1;
if [ $(tc_status) -gt 0 ]; then echo "OK!"; fi
I am trying to write a bash script that detects if a service has changed state. I have this so far:
while true; do
if [ -z "$(netstat -tulpn | grep 51827)" ];
then
echo notinuse
else
echo inuse
fi
sleep 5
done
It works but it will endlessly write when the service is up or down, and I only want it to report on the first instance of a state change. So report when the service was down, and then up as well as when it was up and then went down.
I started to create loop counters and comparing to a previous run but I got into a complete mess of variables. Can anyone help?
if [ -z "$(netstat -tulpn | grep 51827)" ];
then
echo notinuse
notify_status="notinuse-sent"
else
echo inuse
notify_status="inuse-sent"
fi
while true; do
if [ -z "$(netstat -tulpn | grep 51827)" ];
then
if [ $notify_status = "notinuse-sent" ]; then
echo "already notified"
else
echo notinuse
$notify_status="notinuse-sent"
fi
else
if [ $notify_status = "inuse-sent" ]; then
echo "already notified"
else
echo inuse
$notify_status="inuse-sent"
fi
fi
sleep 5
done
I'm getting into the error for bash shell [: : integer expression expected" while running below script.
#!/bin/bash
sm=$(ps -e | grep sendmail > /dev/null 2>&1)
pm=$(/etc/init.d/postfix status > /dev/null 2>&1)
check_mail(){
if [ "$sm" -eq 0 ]; then
echo "Service Status: Sendmail is Running!"
elif [ "$pm" -eq 0 ]; then
echo "Service Status: Postfix Service is Running!"
else
echo "Service Status: Both Sendmail & Postfix Service is Not Running On $(uname -n)"
fi
}
check_mail
While running the above script it's simply showing the output of else
condition.
Service Status: Both Sendmail & Postfix Service is Not Running On host
Though, i have tested "==" rather "-eq" for comparison and [[]] but did not worked.
I assume you are trying to assess presence of sendmail in the process list. You should change your code to this :
#!/bin/bash
check_mail(){
if
ps -e | grep sendmail > /dev/null 2>&1
then
echo "Service Status: Sendmail is Running!"
elif
/etc/init.d/postfix status > /dev/null 2>&1
then
echo "Service Status: Postfix Service is Running!"
else
echo "Service Status: Both Sendmail & Postfix Service is Not Running On $(uname -n)"
fi
}
check_mail
The reason your original code fails is that you capture the output of commands using command substitution $(). The standard output, that is, not the exit code. Then, when using the [ -eq ] test, which expects an integer argument (which your variable does not contain), it fails with the message you get. Since both tests always fail, the else clause is entered.
By putting the actual commands inside the conditions of the if statement, you are using the actual numerical return code (0 for true, non-zero for false), which is what you want here.
It seems to me that you are confusing the exit-status of a program with the output.var=$(command) will put the output of command in var. As said in 123's comment, because you redirect everything to /dev/null, there is no output, and therefore, sm and pm are empty.
If you want to see the exit status, use $?:
#!/bin/bash
typeset -i pm
typeset -i sm
ps -e | grep sendmail > /dev/null 2>&1
sm=$?
/etc/init.d/postfix status > /dev/null 2>&1
pm=$?
check_mail(){
if [ $sm -eq 0 ]; then
echo "Service Status: Sendmail is Running!"
elif [ $pm -eq 0 ]; then
echo "Service Status: Postfix Service is Running!"
else
echo "Service Status: Both Sendmail & Postfix Service is Not Running On $(uname -n)"
fi
}
check_mail
I'm installing Tomcat6 and using the following for /etc/init.d/tomcat6:
#!/bin/bash
# description: Tomcat6 service
# processname: java
# chkconfig: - 99 1
## Note: CATALINA_HOME and CATALINA_PID are set elsewhere.##
# Source function library.
. /etc/init.d/functions
# Source sysconfig for tomcat6
if [ -f /etc/sysconfig/tomcat6 ]; then
. /etc/sysconfig/tomcat6
fi
[ -d "$CATALINA_HOME" ] || { echo "Tomcat requires $CATALINA_HOME."; exit 1; }
case $1 in
start|stop|run)
if su $TOMCAT_USER bash -c "cd $CATALINA_HOME/logs; $CATALINA_HOME/bin/catalina.sh $1"; then
echo -n "Tomcat $1 successful"
[ $1 == "stop" ] && rm -f $CATALINA_PID
else
echo -n "Error in Tomcat $1: $?"
fi
;;
restart)
$0 start
$0 stop
;;
status)
if [ -f "$CATALINA_PID" ]; then
read kpid < "$CATALINA_PID"
if ps --pid $kpid 2>&1 1>/dev/null; then
echo "$0 is already running at ${kpid}"
else
echo "$CATALINA_PID found, but $kpid is not running"
fi
unset kpid
else
echo "$0 is stopped"
fi
;;
esac
exit 0
The problem, as noted in this related ticket, is that Chef checks the "status" of a service and will not start it if the "status" command returns an exit code of "0". Which it always does because the script itself completes successfully, regardless of whether the service is running or not.
I need to adapt my init script to return an exit code of 3 if the service is not running, per the guidelines for Init scripts posted here:
0 program is running or service is OK
1 program is dead and /var/run pid file exists
2 program is dead and /var/lock lock file exists
3 program is not running
4 program or service status is unknown
5-99 reserved for future LSB use
100-149 reserved for distribution use
150-199 reserved for application use
200-254 reserved
I modified my initial script to:
#!/bin/bash
# description: Tomcat6 service
# processname: java
# chkconfig: - 99 1
# Source function library.
. /etc/init.d/functions
# Source sysconfig for tomcat6
if [ -f /etc/sysconfig/tomcat6 ]; then
. /etc/sysconfig/tomcat6
fi
[ -d "$CATALINA_HOME" ] || { echo "Tomcat requires $CATALINA_HOME."; exit 1; }
exit_var=0
case $1 in
start|stop|run)
if su $TOMCAT_USER bash -c "cd $CATALINA_HOME/logs; $CATALINA_HOME/bin/catalina.sh $1"; then
echo -n "Tomcat $1 successful"
[ $1 == "stop" ] && rm -f $CATALINA_PID
else
echo -n "Error in Tomcat $1: $?"
exit_var=1
fi
;;
restart)
$0 start
$0 stop
;;
status)
if [ -f "$CATALINA_PID" ]; then
read kpid < "$CATALINA_PID"
if ps --pid $kpid 2>&1 1>/dev/null; then
echo "$0 is already running at ${kpid}"
exit_var=0
else
echo "$CATALINA_PID found, but $kpid is not running"
exit_var=4
fi
unset kpid
else
echo "$0 is stopped"
exit_var=3 # Fixes issue with Chef not starting a stopped service.
fi
;;
esac
exit $exit_var
But those aren't ACTUALLY changing the exit codes for the script. How can I set different exit codes for different case scenarios?
Version Info:
OS: CentOS 6.5
Chef: 10.20
Tomcat: 6.0.39
You have the right idea, but you have exit_var=3 in the wrong place. I have placed it below to equal 3 for the status when it is already running:
status)
if [ -f "$CATALINA_PID" ]; then
read kpid < "$CATALINA_PID"
if ps --pid $kpid 2>&1 1>/dev/null; then
echo "$0 is already running at ${kpid}"
## Fixes issue with Chef not starting a stopped service.
exit_var=3 ## this is the condition of already running
else
echo "$CATALINA_PID found, but $kpid is not running"
exit_var=4
fi
unset kpid
else
echo "$0 is stopped"
exit_var=5 # (renumbered 5 set as you desire)
fi
;;
esac
exit $exit_var
I'm new in Shellscript, and i'm getting some problems. I need a script to check if the services are running or not, if its not running, and dont exist the flag, start all services. What i'm doing wrong?
#!/bin/bash
file= "$PIN_HOME/apps/DE_BILL_MI_BRM/alarmistica/flags/intervencao.flag"
# Check if services are running
for service in $BRM_SERVICES
do
if [ps -ef | grep $service | grep -v grep | awk 'NR>1{for (i=1;i<=NF;i++)if($i==1) print "Services not running", i}' ]; then
echo $service " is not running correctly"
else
if [ -f "$file" ]; then
echo "Flag exists. The service will not start"
else
echo "$file not found. Starting all services"
pin_ctl start all
fi
fi
done
When ($i==1), the services is not running!
But the results is not corresponding. For exemple, when the services are down, the script dont start the services...
For checking process tables, use pgrep instead.
#!/bin/bash
file= "$PIN_HOME/apps/DE_BILL_MI_BRM/alarmistica/flags/intervencao.flag"
# Check if services are running
for service in $BRM_SERVICES
do
pgrep -f "$service";
exstat=$?; # This checks the exit status
if [ "$exstat" -eq 0 ] && ! [ -f "$file" ]; then
echo "pgrep returned exit status $extstat";
else
echo "$file not found. Starting all services"
pin_ctl start all
fi
done