2

i have a short script in bash, which need to run as daemon on background. It's based on inotifywait, which should wait for changes on specified folder and in case of any changes it should runs copy process.

#! /bin/sh    
case "$1" in
  start)
                dir=/var/www/www/source/
                target=/var/www/www/htdocs/application/cache/target/

                inotifywait -m "$dir" --format '%w%f' -e close_write |
                    while read file; do
                        cp  "$file" "$target"
                    done        
        ;;
  stop)

        ;;
esac

i already placed it to /etc/init.d, after save run update-rc.d myscript defaults, but now, when i try start it throw service start command it stop stucked on messages from inotifywait.

/etc/init.d/bash start
Setting up watches.
Watches established.

Can you please give me some hint how to run it in background process withouth any output messages (in ideal way immediately after startup)?

  • 3
    have you had a look at "nohup"? – Tom Sep 17 '15 at 13:25
  • nohup could be not enough, you also need to [disown](http://linux.about.com/library/cmd/blcmdl1_disown.htm) the process. Otherwise it will be killed when you log out from parent shell console. – DukeLion Sep 18 '15 at 04:10

3 Answers3

3

You could use screen, or as suggested in a comment, nohup. Either could be used in an automated way such as with an init script.

In the case of screen you might need to take special care it will successfully open a screen session if used from something like an init script. Specifically setting the right $TERM environment and running it as a particular user.

If done correctly it has the added benefit of attaching to the screen session and detaching it. Though for your particular purpose screen may be a bit overkill.

Also take a look at /etc/init.d/skeleton which provides a template to create init scripts.

The following line, part of the do_start() function may just do what you need:

start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON

You would only have to change the variables at the beginning to point to your script and related things and it could work as is.

aseq
  • 4,550
  • 1
  • 22
  • 46
1

So I got this to work, but its a pretty ugly hack. For how to properly write init scripts I suggest this link.

What I wanted to do was just put the process in the background with "&".

/etc/init.d/myinitscript.sh

    #! /bin/sh
    case "$1" in
      start)
        dir=/var/www/www/source/
        target=/var/www/www/htdocs/application/cache/target/

        inotifywait -m "$dir" --format '%w%f' -e close_write |
          while read file; do
            cp  "$file" "$target"
          done & ## <--- why not just put it in the background?
      ;;

      stop)
      ;;
    esac

This "works"... for certain values of "work". "myinitscript.sh" runs on start, and does what it is supposed to do, but results in this hung process:

$ ps aux | grep -i init
[... snip ...]
root      2341  0.0  0.1   4096   600 ?        Ss   18:02   0:00 startpar -f -- myinitscript.sh
[... snip ...]

The cause of and possible solutions to this problem can be found here.

My subsequent solution is ugly, and if you're doing this in production, then you're doing it wrong.

I'm using two scripts, one in /etc/init.d and another in /root.

/etc/init.d/myinitscript.sh

    #! /bin/sh
    case "$1" in
      start)
        /root/initscriptbody.sh > /dev/null 2>&1
      ;;

      stop)
      ;;
    esac

Not re-directing stdout and stderr to /dev/null results in the hung 'starpar' process. The second script contains all the functionality and it is here it can be put in the background without resulting in the hung 'starpar' process:

/root/initscriptbody.sh

    #! /bin/sh
    dir=/var/www/www/source/
    target=/var/www/www/htdocs/application/cache/target/

    inotifywait -m "$dir" --format '%w%f' -e close_write |
    while read file
    do
        cp  "$file" "$target"
    done & ## <-- no problem backgrounding this now
Morgan
  • 371
  • 1
  • 3
  • It's a solution, but I am not sure that re-inventing the wheel is very useful bin that regard. The skeleton init script template would have done all that for you and saved you the trouble writing your own with all possible mistakes, in addition it would have a consistent format making future maintenance easier. But if you have the time and want to learn, then by all means. :-) – aseq Sep 18 '15 at 18:16
1

One possible approach is to use Daemontools to start your bash script. Daemontools is a daemon that control your script execution - listens it's stdout and restarts if it exits. There's also some alternatives like supervisord or running your script with Systemd service unit

DukeLion
  • 3,239
  • 1
  • 17
  • 19