6

Usually I add "&" character to start my process in backgroud, exemple :

user@pc:~$ my_script &

But how can I make it in background without "&" character ?

#!/bin/bash

#What can I add here to hide current process ($$) and to release focus ?

start_server()
{   
    #my script here with infinite loop ...
}

Thanks guys.

  • 1
    Perhaps using a shell script? See this SO question: http://stackoverflow.com/questions/3430330/best-way-to-make-a-shell-script-daemon – AST Aug 03 '15 at 17:06
  • 4
    `&` will run a task in background **but a background task is not equal to a daemon**. It is still attached to the terminal where you started it. Once you close the terminal the process will receive `SIGHUP` and die. You may prevent from that using the `nohup` command or bash's job control builtin `disown`.. However when you want to use `disown` the process must be send to background before – hek2mgl Aug 03 '15 at 17:50
  • 1
    BTW, in general, this is the wrong way to run a service. Consider using your operating system's process supervision system -- launchd on MacOS, upstart on Ubuntu, systemd on Fedora and RHEL/CentOS 7 -- or installing one of your choice; DJB's daemontools and its BSD-licensed clone runit are good choices that work on any POSIX-compliant OS without needing to replace init. – Charles Duffy Aug 03 '15 at 18:24
  • 1
    @CharlesDuffy On Ubuntu (14.10) it's also systemd already. They were really fast to integrate it, I was astonished. Btw, on Debian based systems you can use `start-stop-daemon` which is part of the `dpkg` package, meaning it is always installed. IMHO there are a indeed use cases where you want to start a daemon but don't want `init` to control it. `start-stop-daemon` will do it. – hek2mgl Aug 03 '15 at 18:27

1 Answers1

3
#!/bin/bash

if [[ "$1" != "--nodaemon" ]]; then
    ( "$0" --nodaemon "$@" </dev/null &>/dev/null & )
else
    shift
fi

#...rest of script

What this does is check to see if its first argument is "--nodaemon", and if so fire itself ("$0") off in the background with the argument "--nodaemon", which'll prevent it from trying to re-background itself in a sort of infinite loop.

Note that putting this as the first thing in the script will make it always run itself in the background. If it only needs to drop into the background under certain conditions (e.g. when run with the argument "start"), you'd have to adjust this accordingly. Maybe something like this:

#!/bin/bash

start_server()
{   
    #my script here with infinite loop ...
}

if [[ "$1" = "start" ]]; then
    ( "$0" start-nodaemon </dev/null &>/dev/null & )
elif [[ "$1" = "start-nodaemon" ]]; then
    start_server
elif #.....
Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
  • 1
    How does this answer the question? – hek2mgl Aug 03 '15 at 17:51
  • I placed : ( "$0" start-nodaemon /dev/null & ) but still not working. – M. LAKHDARI Aug 03 '15 at 18:11
  • 1
    @hek2mgl it makes the script self-daemonizing. Using a decent process supervisor (as you and Charles Duffy suggested) is a better alternative *if* one's available and appropriate for the purpose; I'm just answering the question as asked. – Gordon Davisson Aug 03 '15 at 19:53
  • @M.LAKHDARI that snippet will need to be adjusted based on how you're running the script. If you want me to do the adaptation, you'll have to provide more information about how the script gets run. (Or, if there's a process manager available, just drop this approach and use that instead.) – Gordon Davisson Aug 03 '15 at 19:55
  • @GordonDavisson it's really not important my start_server() function, I make trainings that's all, and all what I need is to trun my script in background, from the script it self. is it possible ? – M. LAKHDARI Aug 04 '15 at 07:17
  • @M.LAKHDARI If you need the script to always auto-background itself, just use the first snippet. – Gordon Davisson Aug 05 '15 at 03:16