{"id":33915,"date":"2016-05-04T10:01:49","date_gmt":"2016-05-04T04:31:49","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=33915"},"modified":"2016-05-04T17:11:21","modified_gmt":"2016-05-04T11:41:21","slug":"daemonizing-a-process-in-linux","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/daemonizing-a-process-in-linux\/","title":{"rendered":"Daemonizing a Process in Linux"},"content":{"rendered":"<p>Most of the times when we need to run some Java, Node.js or python program in background, so it could stay running even after you leave console all we do is put &#8220;&amp;&#8221; in the end of the command.<\/p>\n<p><code>$java -jar SimpleService.jar &amp;<\/code><\/p>\n<p>The problem here is that when you leave the bash shell your process will become &#8220;Orphan&#8221; and it&#8217;s up to the OS if INIT should adopt the process or kill the process.<\/p>\n<p>To fix this we can force the process to be detached from your shell and become child process of INIT by putting nohup in front of command.<\/p>\n<p><code>$nohup java -jar SimpleService.jar &amp;<\/code><\/p>\n<p>It&#8217;s all good for testing purposes, but services are supposed to run as \u201cdaemons\u201d under some service supervisor. You can find many service supervisors with which you manage your services on Linux and we will cover few of the defaults that come\u00a0with Linux.<\/p>\n<h3>Why do you need it ?<\/h3>\n<p><strong>a.<\/strong> auto start\/stop the service on startup\/shutdown<br \/>\n<strong>b.<\/strong> controlling which service should start first<br \/>\n<strong>c.<\/strong> controlling which service should stop first is equally important<br \/>\n<strong>d.<\/strong> INIT controlled processes directly which provides more options like respawn, post-start, etc..<\/p>\n<h3>Ubuntu services using Upstart<\/h3>\n<p>Modify the script according to your setup:<\/p>\n<p><code>$sudo vi \/etc\/init\/java-app.conf<\/code><\/p>\n<p>[js]author &quot;nitin&quot;<br \/>\ndescription &quot;start and stop java-app for Ubuntu (upstart)&quot;<br \/>\nversion &quot;1.0&quot;<\/p>\n<p>start on started networking<br \/>\nstop on runlevel [!2345]<\/p>\n<p># Automatically Respawn a process if fails, try max 5 times in 60 sec then give up<br \/>\nrespawn<br \/>\nrespawn limit 5 60<\/p>\n<p># Open files Limit<br \/>\nlimit nofile 32768 32768<\/p>\n<p>env APPUSER=&quot;admin&quot;<br \/>\nenv APPBIN=&quot;\/usr\/bin\/java&quot;<br \/>\nenv APPARGS=&quot;-jar \/opt\/app\/SimpleService.jar&quot;<\/p>\n<p>script<br \/>\n  exec su &#8211; $APPUSER -c &quot;$APPBIN $APPARGS&quot;<br \/>\nend script<\/p>\n<p>post-stop script<br \/>\n  sleep 2<br \/>\nend script[\/js]<\/p>\n<p>Check the configuration:<br \/>\n<code>$init-checkconf \/etc\/init\/java-app.conf<\/code><\/p>\n<p>Reload New configuration:<br \/>\n<code>$sudo initctl reload-configuration<\/code><\/p>\n<p>Check is service is known to Upstart:<br \/>\n<code>$sudo initctl list |grep java<\/code><\/p>\n<p>Start the service with:<br \/>\n<code>$sudo start java-app<\/code><\/p>\n<p><strong>Note:<\/strong> For any errors look into \/var\/log\/syslog and \/var\/log\/upstart\/*<\/p>\n<h3>Debian and Ubuntu services using SysVinit<\/h3>\n<p>Modify the script according to your setup.<\/p>\n<p><code>$sudo vi \/etc\/init.d\/java-app<\/code><\/p>\n<p>[js]#!\/bin\/sh<\/p>\n<p>### BEGIN INIT INFO<br \/>\n# Provides: daemon<br \/>\n# Required-Start: $local_fs $network $syslog<br \/>\n# Required-Stop: $local_fs $network $syslog<br \/>\n# Default-Start: 2 3 4 5<br \/>\n# Default-Stop: 0 1 6<br \/>\n# Short-Description: Java-app<br \/>\n# Description: Java-app start-stop-daemon &#8211; Debian<br \/>\n### END INIT INFO<\/p>\n<p>NAME=&quot;java-app&quot;<br \/>\nPATH=&quot;\/usr\/local\/sbin:\/usr\/local\/bin:\/sbin:\/bin:\/usr\/sbin:\/usr\/bin&quot;<br \/>\nAPPDIR=&quot;\/opt\/app&quot;<br \/>\nAPPBIN=&quot;\/usr\/bin\/java&quot;<br \/>\nAPPARGS=&quot;-jar \/opt\/app\/SimpleService.jar&quot;<br \/>\nUSER=&quot;admin&quot;<br \/>\nGROUP=&quot;admin&quot;<\/p>\n<p># Include functions<br \/>\nset -e<br \/>\n. \/lib\/lsb\/init-functions<\/p>\n<p>start() {<br \/>\n  printf &quot;Starting &#8216;$NAME&#8217;&#8230; &quot;<br \/>\n  start-stop-daemon &#8211;start &#8211;chuid &quot;$USER:$GROUP&quot; &#8211;background &#8211;make-pidfile &#8211;pidfile \/var\/run\/$NAME.pid &#8211;chdir &quot;$APPDIR&quot; &#8211;exec &quot;$APPBIN&quot; &#8212; $APPARGS || true<br \/>\n  printf &quot;done\\n&quot;<br \/>\n}<\/p>\n<p>#We need this function to ensure the whole process tree will be killed<br \/>\nkilltree() {<br \/>\n  local _pid=$1<br \/>\n  local _sig=${2-TERM}<br \/>\n  for _child in $(ps -o pid &#8211;no-headers &#8211;ppid ${_pid}); do<br \/>\n    killtree ${_child} ${_sig}<br \/>\n  done<br \/>\n  kill -${_sig} ${_pid}<br \/>\n}<\/p>\n<p>stop() {<br \/>\n  printf &quot;Stopping &#8216;$NAME&#8217;&#8230; &quot;<br \/>\n  [ -z `cat \/var\/run\/$NAME.pid 2&amp;gt;\/dev\/null` ] || \\<br \/>\n  while test -d \/proc\/$(cat \/var\/run\/$NAME.pid); do<br \/>\n    killtree $(cat \/var\/run\/$NAME.pid) 15<br \/>\n  sleep 0.5<br \/>\n  done<br \/>\n  [ -z `cat \/var\/run\/$NAME.pid 2&amp;gt;\/dev\/null` ] || rm \/var\/run\/$NAME.pid<br \/>\n  printf &quot;done\\n&quot;<br \/>\n}<\/p>\n<p>status() {<br \/>\n  status_of_proc -p \/var\/run\/$NAME.pid &quot;&quot; $NAME &amp;amp;&amp;amp; exit 0 || exit $?<br \/>\n}<\/p>\n<p>case &quot;$1&quot; in<br \/>\n    start)<br \/>\n    start<br \/>\n  ;;<br \/>\n    stop)<br \/>\n    stop<br \/>\n  ;;<br \/>\n    restart)<br \/>\n    stop<br \/>\n    start<br \/>\n  ;;<br \/>\n    status)<br \/>\n    status<br \/>\n  ;;<br \/>\n    *)<br \/>\n    echo &quot;Usage: $NAME {start|stop|restart|status}&quot; &amp;gt;&amp;amp;2<br \/>\n    exit 1<br \/>\n  ;;<br \/>\nesac<\/p>\n<p>exit 0[\/js]<\/p>\n<p>Make sure the script is executable:<br \/>\n<code>$chmod +x \/etc\/init.d\/java-app<\/code><\/p>\n<p>Enable the service to auto start in runlevel 2345:<br \/>\n<code>$update-rc.d java-app defaults<\/code><\/p>\n<p>Start the service with:<br \/>\n<code>$service java-app start<\/code><\/p>\n<h3>CentOS\/Redhat services using SysVinit<\/h3>\n<p>Modify the parameter according to your setup:<br \/>\n<code>$sudo vi \/etc\/init.d\/example<\/code><\/p>\n<p>[js]#!\/bin\/sh<br \/>\n#<br \/>\n# example start stop daemon for CentOS (sysvinit)<br \/>\n#<br \/>\n# chkconfig: &#8211; 64 36<br \/>\n# Default-Start: 2 3 4 5<br \/>\n# Default-Stop: 0 1 2 3 4 6<br \/>\n# Required-Start:<br \/>\n# description: java-app start stop daemon for CentOS<br \/>\n# processname: java-app<br \/>\n# pidfile: none<br \/>\n# lockfile: \/var\/lock\/subsys\/java-app<\/p>\n<p># Source function library.<br \/>\n. \/etc\/rc.d\/init.d\/functions<\/p>\n<p># Source networking configuration.<br \/>\n. \/etc\/sysconfig\/network<\/p>\n<p># Check that networking is up.<br \/>\n[ &quot;$NETWORKING&quot; = &quot;no&quot; ] &amp;amp;&amp;amp; exit 0<\/p>\n<p>USER=&quot;admin&quot;<br \/>\nAPPNAME=&quot;java-app&quot;<br \/>\nAPPBIN=&quot;\/usr\/bin\/java&quot;<br \/>\nAPPARGS=&quot;-jar \/opt\/app\/SimpleService.jar&quot;<br \/>\nLOGFILE=&quot;\/var\/log\/$APPNAME\/error.log&quot;<br \/>\nLOCKFILE=&quot;\/var\/lock\/subsys\/$APPNAME&quot;<\/p>\n<p>LOGPATH=$(dirname $LOGFILE)<\/p>\n<p>start() {<br \/>\n  [ -x $prog ] || exit 5<br \/>\n  [ -d $LOGPATH ] || mkdir $LOGPATH<br \/>\n  [ -f $LOGFILE ] || touch $LOGFILE<\/p>\n<p>  echo -n $&quot;Starting $APPNAME: &quot;<br \/>\n  daemon &#8211;user=$USER &quot;$APPBIN $APPARGS &amp;gt;&amp;gt;$LOGFILE &amp;amp;&quot;<br \/>\n  RETVAL=$?<br \/>\n  echo<br \/>\n  [ $RETVAL -eq 0 ] &amp;amp;&amp;amp; touch $LOCKFILE<br \/>\n  return $RETVAL<br \/>\n}<\/p>\n<p>stop() {<br \/>\n  echo -n $&quot;Stopping $APPNAME: &quot;<br \/>\n  killproc $APPBIN<br \/>\n  RETVAL=$?<br \/>\n  echo<br \/>\n  [ $RETVAL -eq 0 ] &amp;amp;&amp;amp; rm -f $LOCKFILE<br \/>\n  return $RETVAL<br \/>\n}<\/p>\n<p>restart() {<br \/>\n  stop<br \/>\n  start<br \/>\n}<\/p>\n<p>rh_status() {<br \/>\n  status $prog<br \/>\n}<\/p>\n<p>rh_status_q() {<br \/>\n  rh_status &amp;gt;\/dev\/null 2&amp;gt;&amp;amp;1<br \/>\n}<\/p>\n<p>case &quot;$1&quot; in<br \/>\n    start)<br \/>\n    rh_status_q &amp;amp;&amp;amp; exit 0<br \/>\n    $1<br \/>\n  ;;<br \/>\n    stop)<br \/>\n    rh_status_q || exit 0<br \/>\n    $1<br \/>\n  ;;<br \/>\n    restart)<br \/>\n    $1<br \/>\n  ;;<br \/>\n    status)<br \/>\n    rh_status<br \/>\n  ;;<br \/>\n    *)<br \/>\n  echo $&quot;Usage: $0 {start|stop|status|restart}&quot;<br \/>\n  exit 2<br \/>\nesac[\/js]<\/p>\n<p>Make sure the script is marked as executable:<br \/>\n<code>$sudo chmod +x \/etc\/init.d\/java-app<\/code><\/p>\n<p>Enable the service to auto start at runlevels 2345:<br \/>\n<code>$sudo chkconfig java-app on<\/code><\/p>\n<p>Start the service with:<br \/>\n<code>$sudo service java-app start<\/code><\/p>\n<p>This is how simple it is to daemonize a process. In my next blog, I will talk about more interesting features available in Linux OS.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Most of the times when we need to run some Java, Node.js or python program in background, so it could stay running even after you leave console all we do is put &#8220;&amp;&#8221; in the end of the command. $java -jar SimpleService.jar &amp; The problem here is that when you leave the bash shell your [&hellip;]<\/p>\n","protected":false},"author":747,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":49},"categories":[2348],"tags":[248,3290,3291,260,3292,3287,3289,3288],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/33915"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/747"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=33915"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/33915\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=33915"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=33915"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=33915"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}