I am new to php daemons. I am using the below script to fire Daemon.php script. But i am getting error while executing this below bash script via shell
The error is,
exit: 0RETVAL=0: numeric argument required
Please help me resolve this error
#!/bin/bash
#
# /etc/init.d/Daemon
#
# Starts the at daemon
#
# chkconfig: 345 95 5
# description: Runs the demonstration daemon.
# processname: Daemon
# Source function library.
#. /etc/init.d/functions
#startup values
log=/var/log/Daemon.log
#verify that the executable exists
test -x /home/godlikemouse/Daemon.php || exit 0RETVAL=0
#
# Set prog, proc and bin variables.
#
prog="Daemon"
proc=/var/lock/subsys/Daemon
bin=/home/godlikemouse/Daemon.php
start() {
# Check if Daemon is already running
if [ ! -f $proc ]; then
echo -n $"Starting $prog: "
daemon $bin --log=$log
RETVAL=$?
[ $RETVAL -eq 0 ] && touch $proc
echo
fi
return $RETVAL
}
stop() {
echo -n $"Stopping $prog: "
killproc $bin
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f $proc
echo
return $RETVAL
}
restart() {
stop
start
}
reload() {
restart
}
status_at() {
status $bin
}
case "$1" in
start)
start
;;
stop)
stop
;;
reload|restart)
restart
;;
condrestart)
if [ -f $proc ]; then
restart
fi
;;
status)
status_at
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
exit 1
esac
exit $?
exit $RETVAL
This line produces the error:
test -x /home/godlikemouse/Daemon.php || exit 0RETVAL=0
If you want to set the the value of RETVAL to 0 you first need to remove the 0 as you can not have variables that start with a number.
Then you remove the value set from the second statement so it will exit in case Daemon.php does not exist.
test -x /home/godlikemouse/Daemon.php || exit
You can also remove the 2 empty echo statements inside the start and stop functions as the do nothing.
There are also errors in the case statement. You need to quote the case options and can remove the last exit block as the exit $? will trigger the exit before.
case "$1" in
"start")
start
;;
"stop")
stop
;;
"reload"|"restart")
restart
;;
"condrestart")
if [ -f $proc ]; then
restart
fi
;;
"status")
status_at
;;
There is several syntax and logic errors in this script presented. To highlight several:
echo $"Usage (should be just echo "Usage ..." since the string in ".." is not a variable
Double exit statements, the second one for $RETVAL is never ran.
exit 0RETVAL is not the same as exit $RETVAL, and one should just be using exit 1 instead to denote an error, exit 0 means the script ran correctly
$prog is defined but never used
test -x is to check for executable bit enabled in the given path. test -f is safer when testing for a file, test -d safer for testing directories, and test -L is safer when testing symlinks. Combine the test -f and test -x to ensure there is no race conditions or worst. (example: (test -f /home/godlikemouse/Daemon.php && test -x /home/godlikemouse/Daemon.php) || exit 1))
Further details on creating sysv init scripts can be read at http://refspecs.linuxbase.org/LSB_3.0.0/LSB-generic/LSB-generic/iniscrptact.html and bash scripting can be read at http://www.tldp.org/LDP/abs/html/index.html. It is strongly encouraged to learn both before writing system control programs such as init scripts.
Related
#function: usage
#description: 1. parse command line arguments
# 2. for illegal usages, print usage message and exit 1
# 3. otherwise, communicate to main() what flags are set
function usage {
while getopts ":gn:" OPT; do
case $OPT in
g) ;;
n) name=$OPTARG;;
:) echo "$USAGE"
exit 1
;;
\?) echo "$USAGE"
exit 1
;;
*) echo "$USAGE"
exit 1
esac
done
shift $(($OPTIND + 1))
}
#function: main
#description: For Part 1:
# 1. use usage() to parse command line arguments
# 2. echo corresponding messages for each flag that is set
#
# For Part 2:
# Kill processes based on the case return by `usage`
function main {
# TODO change the condition so that this line prints when '-g' is set
usage()
if [ ! -z "g" ]; then
echo graceful kill is present
fi
# TODO change the condition so that this line prints when '-n' is set
if [ ! -z "n" ]; then
echo process name is present
fi
main $#
This is what I write so far, I want to have something like
./KillByName -g 24601
graceful kill is present
or
./KillByName -g
Usage: KillByName [-g] -n or KillByName [-g]
or
./KillByName -g -n bash
graceful kill is present
process name is present
essentially, if there is -g, then it shows it is gracefully killed, and with a name. If there is -n, then it says the name exits and with a name.
I found my script can print the message of whether graceful kill present or name present, but cannot print the mistake of $USAGE.
BTW: this is only for information of usage, not actually program of killing the program
First of all,
usage()
is not the way you call a function, It should've been
usage
But there is a problem with that, you're not passing any arguments to the function usage from main, so it should've been
usage "$#" # Double quotes to prevent word splitting
Though the term "graceful killing" is a paradox in itself, you could do something like
while getopts ":gn:" OPT; do
gracekill=0; //s
case $OPT in
g) gracekill=1;;
n) name=$OPTARG;;
:) echo "$USAGE"
exit 1
;;
\?) echo "$USAGE"
exit 1
;;
*) echo "$USAGE"
exit 1
esac
done
echo "$gracekill $name" # Mind double quotes
Then do this :
result=$(usage "$#")
if [ ${result:0:1} -eq '1' ]
then
#gracefully kill the application
kill -9 $( pgrep "${result:1}" )
else
#ruthlessly terminate it
kill -15 $( pgrep "${result:1}" )
fi
For more on ${var:offset:length} form, see [ param expansion ]
Notes : I assume that you're passing the process names to the function, if you're passing the process number, then you don't need the
pgpep ie kill -15 $( pgrep "${result:1}" ) will become kill -15 "${result:1}" and so.Goodluck!
I have the following code for a service that I'm trying to have automatically start on boot.
#!/bin/sh
# Source function library.
. /etc/rc.d/init.d/functions
RETVAL=0
prog='foo'
exec="/usr/sbin/$prog"
pidfile="/var/run/$prog.pid"
lock_file="/var/lock/subsys/$prog"
logfile="/var/log/$prog"
if [ -f /etc/default/foo ]; then
. /etc/default/foo
fi
if [ -z $QUEUE_TYPE ]; then
echo 'ENV variable QUEUE_TYPE has not been set, please set it in /etc/default/foo'
exit 1
fi
get_pid() {
cat "$pidfile"
}
is_running() {
[ -f "$pidfile" ] && ps `get_pid` > /dev/null 2>&1
}
case "$1" in
start)
echo -n "Starting Consul daemon: "
#
daemon --pidfile $pidfile --check foo --user my-user "my app stuff here"
echo
;;
stop)
echo -n 'Stopping Consul daemon: '
killproc foo
echo
;;
status)
status $pidfile
RETVAL=$?
#status -p $pidfile -l $prog
#[ $RETVAL -eq 0 ] && RETVAL=$?
#RETVAL=$?
#if is_running; then
# echo 'Running'
#else
# echo 'Not Running'
#fi
#status foo
#RETVAL=$?
;;
restart)
$0 stop
$0 start
RETVAL=$?
;;
*)
echo 'Usage: foo {start|stop|status|restart}'
exit 1
esac
exit $RETVAL
When I run sudo service foo status it says that it hasn't been started which is correct. After running sudo service foo start and then running the status command, it tells me that the service hasn't been started. I'm not sure what is causing this to happen. I looked at the configurations for other init.d scripts to see how they were handling this and tried to follow their lead. Is there something obvious here that I'm doing wrong or something else that I may be unaware of that's causing this problem?
I am trying to monitor gearman by nagios for that I am using script check_gearman.sh.
Localhost is where gearman server running.
When I run
./check_gearman.sh -H localhost -p 4730 -t 1000
It results in:
CRITICAL: gearman: gearman_client_run_tasks : gearman_wait(GEARMAN_TIMEOUT) timeout reached, 1 servers were poll(), no servers were available, pipe:false -> libgearman/universal.cc:331: pid(613)
Can some one please help me out in this.
below is script
#!/bin/sh
#
# gearman check for nagios
# written by Georg Thoma (georg#thoma.cn)
# Last modified: 07-04-2014
#
# Description:
#
#
#
PROGNAME=`/usr/bin/basename $0`
PROGPATH=`echo $0 | sed -e 's,[\\/][^\\/][^\\/]*$,,'`
REVISION="0.04"
export TIMEFORMAT="%R"
. $PROGPATH/utils.sh
# Defaults
hostname=localhost
port=4730
timeout=50
# search for gearmanstuff
GEARMAN_BIN=`which gearman 2>&1 | grep -v "no gearman in"`
if [ "x$GEARMAN_BIN" == "x" ] ; then # result of check is empty
echo "gearman executable not found in path"
exit $STATE_UNKNOWN
fi
GEARADMIN_BIN=`which gearadmin 2>&1 | grep -v "no gearadmin in"`
if [ "x$GEARADMIN_BIN" == "x" ] ; then # result of check is empty
echo "gearadmin executable not found in path"
exit $STATE_UNKNOWN
fi
print_usage() {
echo "Usage: $PROGNAME [-H hostname -p port -t timeout]"
echo "Usage: $PROGNAME --help"
echo "Usage: $PROGNAME --version"
}
print_help() {
print_revision $PROGNAME $REVISION
echo ""
print_usage
echo ""
echo "gearman check plugin for nagios"
echo ""
support
}
# Make sure the correct number of command line
# arguments have been supplied
if [ $# -lt 1 ]; then
print_usage
exit $STATE_UNKNOWN
fi
# Grab the command line arguments
exitstatus=$STATE_WARNING #default
while test -n "$1"; do
case "$1" in
--help)
print_help
exit $STATE_OK
;;
-h)
print_help
exit $STATE_OK
;;
--version)
print_revision $PROGNAME $REVISION
exit $STATE_OK
;;
-V)
print_revision $PROGNAME $REVISION
exit $STATE_OK
;;
-H)
hostname=$2
shift
;;
--hostname)
hostname=$2
shift
;;
-t)
timeout=$2
shift
;;
--timeout)
timeout=$2
shift
;;
-p)
port=$2
shift
;;
--port)
port=$2
shift
;;
*)
echo "Unknown argument: $1"
print_usage
exit $STATE_UNKNOWN
;;
esac
shift
done
# check if server is running and replys to version query
VERSION_RESULT=`$GEARADMIN_BIN -h $hostname -p $port --server-version 2>&1 `
if [ "x$VERSION_RESULT" == "x" ] ; then # result of check is empty
echo "CRITICAL: Server is not running / responding"
exitstatus=$STATE_CRITICAL
exit $exitstatus
fi
# drop funtion echo to remove functions without workers
DROP_RESULT=`$GEARADMIN_BIN -h $hostname -p $port --drop-function echo_for_nagios 2>&1 `
# check for worker echo_for_nagios and start a new one if needed
CHECKWORKER_RESULT=`$GEARADMIN_BIN -h $hostname -p $port --status | grep echo_for_nagios`
if [ "x$CHECKWORKER_RESULT" == "x" ] ; then # result of check is empty
nohup $GEARMAN_BIN -h $hostname -p $port -w -f echo_for_nagios -- echo echo >/dev/null 2>&1 &
fi
# check the time to get the status from gearmanserver
CHECKWORKER_TIME=$( { time $GEARADMIN_BIN -h $hostname --status ; } 2>&1 |tail -1 )
# check if worker returns "echo"
CHECK_RESULT=`cat /dev/null | $GEARMAN_BIN -h $hostname -p $port -t $timeout -f echo_for_nagios 2>&1`
# validate result and set message and exitstatus
if [ "$CHECK_RESULT" = "echo" ] ; then # we got echo back
echo "OK: got an echo back from gearman server version: $VERSION_RESULT, responded in $CHECKWORKER_TIME sec|time=$CHECKWORKER_TIME;;;"
exitstatus=$STATE_OK
else # timeout reached, no echo
echo "CRITICAL: $CHECK_RESULT"
exitstatus=$STATE_CRITICAL
fi
exit $exitstatus
Thanks in advance.
If you download the mod_gearman package, this contains a much better and more featured check_gearman plugin for Nagios.
With your current plugin, the error message shows that the check script cannot connect to the gearman daemon.
You should verify that port 4370 is listening on localhost, and that there is no local firewall blocking connections. It is likely that you have installed your gearmand on a different port, or have it only listening on the network interface, not on localhost. Or maybe it is not runing at all, or is on a different server from the one running the check...
I have an init script (im running Debian) to start serviio a DLNA server. When i go to start the service i get the following error. Any help would be appreciated. Please note: I'm VERY new to linux/bash/debian.
I get this error: Invalid Syntax: unexpected then on line 43, expected }
With this code:
#! /bin/sh
#
# /etc/init.d/serviio
#
#
### BEGIN INIT INFO
# Provides: serviio
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: Start the serviio DLNA server in headless mode
### END INIT INFO
SERVIIO_HOME="/opt/serviio"
SERVIIO_DAEMON="serviio.sh"
SERVIIO_BIN="$SERVIIO_HOME/bin/$SERVIIO_DAEMON"
SERVIIO_USER="serviio"
# Source function library.
. /lib/lsb/init-functions
RETVAL=0
check() {
# Check that we're a privileged user
[ $(id -u) = 0 ] || exit 4
# Check if SERVIIO_HOME exists
test -d "$SERVIIO_HOME" || exit 5
# Check if SERVIIO_BIN is executable
test -x "$SERVIIO_BIN" || exit 5
}
start() {
check
echo -n "Starting Serviio DLNA server: "
/usr/bin/sudo -u $SERVIIO_USER -H $SERVIIO_BIN -headless &
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch /var/lock/serviio
log_end_msg 0
else
log_end_msg 1
fi
echo
return $RETVAL
}
stop() {
check
echo -n "Shutting down Serviio DLNA daemon: "
killproc "$SERVIIO_BIN"
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f /var/lock/serviio
echo
return $RETVAL
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
force-reload)
restart
;;
restart)
restart
;;
condrestart)
if [ -f /var/lock/serviio ]; then
restart
fi
;;
status)
status serviio.sh
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|force-reload}"
RETVAL=2
esac
exit $RETVAL
I can run this script without getting syntax errors,, but I don't have serviio installed. Anyway, my guess would be that $RETVAL is somehow empty, and that it needs to be in quotes:
if [ "$RETVAL" -eq 0 ]; then
Although I would think that would complain about '[' expecting a unary operator.
The next thing to try would be to comment out sections at a time by prepending "#" to the lines in the section until you can narrow down where the problem is. For example, comment out the whole "start" section, or comment out the "check" function (and make sure you comment out the calls to it, too). That should help narrow it down.
I want to write a simple check upon running mkdir to create a dir. First it will check whether the dir already exists, if it does, it will just skip. If the dir doesn't exist, it will run mkdir, if mkdir fails (meaning the script could not create the dir because it does not have sufficient privileges), it will terminate.
This is what I wrote:
if [ ! -d "$FINALPATH" ]; then
if [[ `mkdir -p "$FINALPATH"` -ne 0 ]]; then
echo "\nCannot create folder at $FOLDERPATH. Dying ..."
exit 1
fi
fi
However, the 2nd if doesn't seem to be working right (I am catching 0 as return value for a successful mkdir). So how to correctly write the 2nd if? and what does mkdir returns upon success as well as failure?
The result of running
`mkdir -p "$FINALPATH"`
isn't the return code, but the output from the program. $? the return code. So you could do
if mkdir -p "$FINALPATH" ; then
# success
else
echo Failure
fi
or
mkdir -p "$FINALPATH"
if [ $? -ne 0 ] ; then
echo Failure
fi
The shorter way would be
mkdir -p "$FINALPATH" || echo failure
also idiomatic:
if mkdir -p "$FINALPATH"
then
# .....
fi
Likewise you can while .....; do ....; done or until ......; do ......; done
Just for completeness, you can exit by issuing:
mkdir -p "$FINALPATH" || { echo "Failure, aborting..." ; exit 1 ; }
Braces are necessary, or else exit 1 would execute in both cases.
Or you can create an abort function like:
errormsg()
{
echo "$1"
echo Aborting...
{ exit 1 ; }
}
And then just call it by issuing:
mkdir -p "$FINALPATH" || errormsg "Failure creating $FINALPATH"
Edited:
Braces, not parenthesis, as parenthesis only exit the subshell.
( Thanks #Charles Duffy )
A function to write a message and exit