PDA

View Full Version : create a daemon for shell script



mathboy314
26th July 2007, 05:28 PM
Hi Folks,

Can someone please tell me how to create my own linux service(daemon) that will execute and run a shell script of my choice? It seems like a no-brainer but I can't find a decent thread on how to actually do it.

Any help is greatly appreciated.

P.S. please please don't respond with "why don't you do this...."

unixguru88
27th July 2007, 09:26 AM
Check out the dozens of examples already available in /etc/init.d. I am not sure what you are trying to do but you can use .bash_profile or .bashrc to run scripts on login.

ibbo
27th July 2007, 11:21 AM
xinetd is your best friend for this.

What you need to do.

1. Choose a port number (i used 9468 for this example) but a `cat /etc/services | grep 9468` will tell you if its in use or not.
2. When you have your port add the following line to /etc/services
loopy 9468/tcp #loop a bit
3. vi /etc/xinet.d/loop and paste this in


# default: on
# description: loop socket server
service loopy
{
port = 9468
socket_type = stream
wait = no
user = nobody
server = /home/<you>/bin/loop.sh
log_on_success += USERID
log_on_failure += USERID
disable = no
}

Save it. "make sure to change <you> to your home dir."
4. create your shell script and save it in your ~/bin folder as loop.sh and chown 755 it.


#!/bin/bash
for i in `seq 50`
do
echo -e "$i\n";
done


5. restart xinet.d
6. telnet <host> 9468

1
2
3
4
5
6
7
etc

And you should be good to go. If it does not work scan your /var/log/messages file for potential errors. You should get the jist of how this works in no time and then you can serve up your scripts.

Have fun

Ibbo

consigliere
9th July 2010, 11:31 PM
ibbo>

I am using Fedora 13. I found /etc/xinet.d but my system does not have xinet.d daemon.

dd_wizard
9th July 2010, 11:42 PM
It's hard to tell what exactly you want to do. Do you want a process to wake up once in a while and execute scripts in a directory? Or maybe you want to schedule a task periodically? Just executing a script followed by an & from the command line effectively daemonizes it. And cron can schedule tasks for you. A little more information would be helpful.

dd_wizard

consigliere
9th July 2010, 11:45 PM
I wrote a Java program and I need to run it as a service (service my-java start|stop|restart) regardless I am logged in or not. This my-java program needs to be in background all the time. Basically what I need is a tutorial or how-to for writing my own service script and place it in /etc/init.d

thanks

dd_wizard
9th July 2010, 11:55 PM
Ah, that's much clearer. As unixguru88 suggested, there are lots of examples in /etc/rc.d/init.d. (The directory /etc/init.d is symbolically linked to /etc/rc.d/init.d.) If you google "writing system V init scripts", you will find quite a few guides that will help you along the way. The file /etc/rc.d/rc.local runs after all the other init scripts and can be used for the service if you don't need all the SysV capabilities.

dd_wizard

consigliere
10th July 2010, 12:44 AM
thanks

:o)

dd_wizard
10th July 2010, 01:08 AM
Welcome. :)

dd_wizard

consigliere
10th July 2010, 02:42 AM
Copied the example from http://www.cyberciti.biz/tips/linux-write-sys-v-init-script-to-start-stop-service.html

But when running it says: /etc/init.d/java.pwd5.alarm: line 12: initlog: command not found

Line 12: initlog -c "echo -n Starting startServer server: "



#!/bin/bash
#
# chkconfig: 35 90 12
# description: startServer
#

# Get function from functions library
. /etc/init.d/functions

# Start the service startServer
start() {
initlog -c "echo -n Starting startServer server: "
/home/edgar/appsJava/serverTCP/startServer &
### Create the lock file ###
touch /var/lock/subsys/startServer
success $"startServer server startup"
echo
}

# Restart the service startServer
stop() {
initlog -c "echo -n Stopping startServer server: "
killproc startServer
### Now, delete the lock file ###
rm -f /var/lock/subsys/startServer
echo
}

### main logic ###
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status startServer
;;
restart|reload|condrestart)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|status}"
exit 1
esac

exit 0

dd_wizard
10th July 2010, 06:47 PM
I grepped for initlog in /etc/rc.d/functions and it's not there in Fedora. When you look at examples, make sure the functions are sourced from /etc/rc.d/init.d/functions. Fedora and some other distros put init scripts in /etc/rc.d/init.d, while other distros put them in /etc/init.d. Fedora does have a sym link from /etc/init.d to /etc/rc.d/init.d, which is why you didn't get an error when /etc/init.d/functions was sourced in your script.

The guides will give useful background information about run levels and general script structure. But for specifics, such as logger function names and file naming conventions, you should use the the Fedora scripts in /etc/rc.d/init.d as your examples. Well, if you look jexec, you'll see it's a bad example of porting a Sun script to Fedora. :)

dd_wizard

consigliere
12th July 2010, 09:42 PM
I made a test script a it worked. When changed the script to start the java app, always said: "startServer dead but subsys locked"

???

---------- Post added at 03:42 PM CDT ---------- Previous post was at 10:58 AM CDT ----------

I can run it now with "service startServer start", but when stopping it, it keeps running. It seems killproc does not kill all started scripts by daemon command. The only killed process is: 12170 pts/6 S 0:00 /bin/bash /etc/init.d/startServer start

Here is a ps -ax display of the processes:


12170 pts/6 S 0:00 /bin/bash /etc/init.d/startServer start
12172 pts/6 S< 0:00 /bin/bash -c ulimit -S -c 0 >/dev/null 2>&1 ; /home/javaServers/appsJava/serverTCP/initServer
12173 pts/6 S< 0:00 /bin/bash /home/javaServers/appsJava/serverTCP/initServer
12174 pts/6 S<l 0:02 /usr/bin/java -jar /home/javaServers/appsJava/serverTCP/ServidorFinal.jar
12225 pts/5


StartServer Service:


#!/bin/bash
#
# chkconfig: 2345 20 80
# description: startServer
#

### BEGIN INIT INFO
# Provides: startServer
# Required-Start: $local_fs $network $remote_fs
# Required-Stop: $local_fs $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Java Server
# Description: Procesa alarmas PWD para clientes PC
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

exec="/home/javaServers/appsJava/serverTCP/initServer"
prog="startServer"

lockfile=/var/lock/subsys/$prog

start() {
[ -x $exec ] || exit 5
echo -n $"Starting $prog: "
# if not running, start it up here, usually something like "daemon $exec"
daemon -20 $exec &
#$exec &
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}

stop() {
echo -n $"Stopping $prog: "
# stop it here, often "killproc $prog"
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}

restart() {
stop
start
}

reload() {
restart
}

force_reload() {
restart
}

rh_status() {
# run checks to determine if the service is running or use generic status
status $prog
}

rh_status_q() {
rh_status >/dev/null 2>&1
}

case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?


initServer to start Java App:


#!/bin/bash
#
/usr/bin/java -jar /home/javaServers/appsJava/serverTCP/ServidorFinal.jar

dd_wizard
12th July 2010, 10:47 PM
What do you see in /var/run while your service is running? From studying killproc in /etc/rc.d/init.d/functions, it's looking for a file with the service name that contains a pid. You may need to kill ServidorFinal.jar, and I'm not sure if killproc is the best way to do that.

Hope that helps,
dd_wizard

consigliere
12th July 2010, 11:06 PM
This is what I see in /var/run:


root@fedora13 /var/run$ dir
total 244K
drwxr-xr-x. 26 root 4.0K Jul 12 12:59 ./
drwxr-xr-x. 21 root 4.0K Jul 6 13:53 ../
-rw-r--r-- 1 root 5 Jul 9 17:09 acpid.pid
srw-rw-rw- 1 root 0 Jul 9 17:09 acpid.socket=
-rw-r--r-- 1 root 5 Jul 9 17:10 atd.pid
-rw-r--r-- 1 root 5 Jul 9 17:10 auditd.pid
drwxr-xr-x. 2 avahi 4.0K Jul 9 17:09 avahi-daemon/
drwxr-xr-x. 2 root 4.0K Feb 15 11:34 console/
drwxr-xr-x. 2 root 4.0K Jul 9 17:09 ConsoleKit/
-rw-r--r-- 1 root 5 Jul 9 17:10 crond.pid
---------- 1 root 0 Jul 9 17:10 cron.reboot
drwxr-xr-x. 2 root 4.0K Jul 9 17:09 dbus/
-rw-r--r-- 1 root 5 Jul 12 12:29 dhclient-eth1.pid
-rw-r--r-- 1 root 5 Jul 9 17:10 gpm.pid
drwx------. 2 haldaemon 4.0K Mar 29 12:20 hald/
-rw-r--r-- 1 root 5 Jul 9 17:09 haldaemon.pid
drwx--x---. 2 root 4.0K Apr 4 12:16 httpd/
-rw-r--r-- 1 root 4 Jul 9 17:09 irqbalance.pid
drwx------. 2 root 4.0K Jul 9 17:09 mdadm/
-rw-r--r-- 1 root 5 Jul 9 17:09 messagebus.pid
drwxr-xr-x. 2 mysql 4.0K Jun 4 16:55 mysqld/
drwxrwxr-x. 2 root 4.0K Jun 24 14:20 netreport/
drwxr-xr-x. 2 root 4.0K Jul 9 17:09 NetworkManager/
-rw-r--r-- 1 root 29 Jul 9 17:09 nm-dhclient-eth1.conf
drwxr-xr-x. 2 root 4.0K Jun 1 22:48 nscd/
drwxr-xr-x. 2 root 4.0K Jan 5 2010 openvpn/
srwxrwxrwx 1 root 0 Jul 9 17:09 pcscd.comm=
drwx-wx-wt 2 root 4.0K Jul 9 17:09 pcscd.events/
-rw-r--r-- 1 root 5 Jul 9 17:09 pcscd.pid
-rw-r--r-- 1 root 65K Jul 9 17:09 pcscd.pub
drwx------. 2 root 4.0K Mar 29 12:41 pluto/
drwxr-xr-x. 2 root 4.0K May 7 14:05 plymouth/
drwxr-xr-x. 4 root 4.0K Jul 6 13:51 pm-utils/
drwxr-xr-x. 2 root 4.0K Apr 13 01:47 ppp/
drwxr-xr-x. 2 root 4.0K Apr 9 09:06 saslauthd/
drwxrwxr-x. 2 root 4.0K Sep 25 2009 screen/
drwxr-xr-x. 2 root 4.0K Feb 15 11:34 sepermit/
drwxr-xr-x. 2 root 4.0K Feb 22 10:53 setrans/
-rw-r--r-- 1 root 5 Jul 9 17:09 sshd.pid
drwx------. 2 root 4.0K Jun 2 04:15 sudo/
-rw------- 1 root 5 Jul 9 17:09 syslogd.pid
-rw-rw-r-- 1 root 6.4K Jul 12 17:00 utmp
drwxr-xr-x. 2 root 4.0K Dec 9 2009 vpnc/
drwxr-xr-x. 2 root 4.0K May 6 20:24 wpa_supplicant/
-rw-r--r-- 1 root 5 Jul 9 17:09 wpa_supplicant.pid


this is what service startServer status displays:


startServer (pid 14279) is running...


and these are the processes related to startServer:


14279 pts/0 S 0:00 /bin/bash /etc/init.d/startServer start
14281 pts/0 S< 0:00 /bin/bash -c ulimit -S -c 0 >/dev/null 2>&1 ; /home/javaServers/appsJava/serverTCP/initServer
14282 pts/0 S< 0:00 /bin/bash /home/javaServers/appsJava/serverTCP/initServer
14283 pts/0 S<l 0:01 /usr/bin/java -jar /home/javaServers/appsJava/serverTCP/ServidorFinal.jar


As you can see, the service only knows the 14279 pid.

dd_wizard
12th July 2010, 11:32 PM
Have you tried killproc $exec?

dd_wizard

consigliere
12th July 2010, 11:56 PM
killproc $exec kills all processes except one:


15732 pts/0 S<l 0:00 /usr/bin/java -jar /home/javaServers/appsJava/serverTCP/ServidorFinal.jar

consigliere
14th July 2010, 07:52 PM
Fixed this way:


#!/bin/bash
#
# chkconfig: 2345 20 80
# description: startServer
#

### BEGIN INIT INFO
# Provides: startServer
# Required-Start: $local_fs $network $remote_fs
# Required-Stop: $local_fs $network $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Java Server
# Description: Procesa alarmas PWD para clientes PC
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

exec="/home/javaServers/appsJava/alarms/initServer"
prog="alarmsViewer"

lockfile=/var/lock/subsys/$prog

start() {
[ -x $exec ] || exit 5
echo -n $"Starting $prog: "
# if not running, start it up here, usually something like "daemon $exec"
daemon -20 $exec &
#$exec &
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}

stop() {
echo -n $"Stopping $prog: "
# stop it here, often "killproc $prog"
killproc $prog
killproc $exec
kill -9 `ps ax | grep alarmsViewer.jar$ | awk '{ print $1 }'`
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}

restart() {
stop
start
}

reload() {
restart
}

force_reload() {
restart
}

rh_status() {
# run checks to determine if the service is running or use generic status
status $prog
}

rh_status_q() {
rh_status >/dev/null 2>&1
}

case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?


Pay attention to the stop() function.