- Run bash script as daemon
- Daemonize a process in shell?
- 2 Answers 2
- Запуск приложения в режиме “daemon” в Linux
- Первый способ
- Второй способ
- Третий способ
- Заказать создание и поддержку безопасной IT-инфраструктуры любой сложности
- "Proper" way to run shell script as a daemon
- Linux Daemon Writing HOWTO
- daemonize Introduction
Run bash script as daemon
To run it as a full daemon from a shell, you’ll need to use setsid and redirect its output. You can redirect the output to a logfile, or to /dev/null to discard it. Assuming your script is called myscript.sh, use the following command:
setsid myscript.sh >/dev/null 2>&1 < /dev/null &
This will completely detach the process from your current shell (stdin, stdout and stderr). If you want to keep the output in a logfile, replace the first /dev/null with your /path/to/logfile.
You have to redirect the output, otherwise it will not run as a true daemon (it will depend on your shell to read and write output).
You'll have to find it's pid and send it a signal. Here's an UNSAFE example for linux systems: kill $(ps -fade | grep myscript.sh | grep -v grep | awk '
@DanielPatrick in bash (and most other shells) this is stdin/stderr/stdout redirection. The > /dev/null (same as 1>/dev/null ) redirects stdout (which is file descriptor 1) to /dev/null. The 2>&1 means redirect all stderr (file descriptor 2) to file descriptor 1, which is already redirected to /dev/null. The
A Daemon is just program that runs as a background process, rather than being under the direct control of an interactive user.
[The below bash code is for Debian systems - Ubuntu, Linux Mint distros and so on]
The simple way:
The simple way would be to edit your /etc/rc.local file and then just have your script run from there (i.e. everytime you boot up the system):
Add the following and save:
#For a BASH script /bin/sh TheNameOfYourScript.sh > /dev/null &
The better way to do this would be to create a Daemon via Upstart:
sudo nano /etc/init/TheNameOfYourDaemon.conf
description "My Daemon Job" author "Your Name" start on runlevel [2345] pre-start script echo "[`date`] My Daemon Starting" >> /var/log/TheNameOfYourDaemonJobLog.log end script exec /bin/sh TheNameOfYourScript.sh > /dev/null &
init-checkconf /etc/init/TheNameOfYourDaemon.conf
Now when you boot up your system, you can see the log file stating that your Daemon is running:
cat /var/log/TheNameOfYourDaemonJobLog.log
• Now you may start/stop/restart/get the status of your Daemon via:
restart: this will stop, then start a service
sudo service TheNameOfYourDaemonrestart restart
start: this will start a service, if it's not running
sudo service TheNameOfYourDaemonstart start
stop: this will stop a service, if it's running
sudo service TheNameOfYourDaemonstop stop
status: this will display the status of a service
sudo service TheNameOfYourDaemonstatus status
You should really indicate the distro this is for, because these commands and paths are not correct on all distros.
Good point sgtPooki. I added a caveat explaining that my example refers to Ubuntu / Mint distributions etc. Thanks for you comment.
You can go to /etc/init.d/ - you will see a daemon template called skeleton.
You can duplicate it and then enter your script under the start function.
you may also consider running the script in background by adding '&' at the end or running it with nohup.
@LuisMuñoz how can I make it run in the background automatically. for instance when you issue /etc/init.d/mysql start, the daemon starts and runs in the background by default.
@DavidOkwii put your code in a function and run it in the background. Check my answer added to this question.
Another cool trick is to run functions or subshells in background, not always feasible though
name() < echo "Do something" sleep 1 ># put a function in the background name & #Example taken from here #https://bash.cyberciti.biz/guide/Putting_functions_in_background
Running a subshell in the background
(echo "started"; sleep 15; echo "stopped") &
Some commentors already stated that answers to your question will not work for all distributions. Since you did not include CentOS in the question but only in the tags, I'd like to post here the topics one has to understand in order to have a control over his/her proceeding regardless of the distribution:
- what is the init daemon (optional)
- what is the inittab file (/etc/inittab)
- what does the inittab file do in your distro (e.g. does it actually run all scripts in /etc/init.d ?)
For your problem, one could start the script on sysinit by adding this line in /etc/inittab and make it respawn in case it terminates:
# start and respawn after termination ttyS0::respawn:/bin/sh /path/to/my_script.sh
The script has to be made executable in advance of course:
chmod +x /path/to/my_script.sh
Daemonize a process in shell?
If I am corrrect, the command is the same as "nohup and background a process". But isn't a daemon more than a nohupped and background process? What steps are missing here to daemonize a process? For example, isn't changing the parent process necessary when daemonizing a process? If yes, how do you do that in bash? I am still trying to understand a related reply https://unix.stackexchange.com/a/177361/674. What other steps and conditions? See my related question https://stackoverflow.com/q/35705451/156458
depends on your definition of daemons. If you merely mean running in the background detached from a terminal then yes you are running firefox as a daemon. "standard" daemons, however, typically are not run by users, have an init script and logging, and typically some sort of security, often apparmor or selinux depending on if you are running Ubuntu or Fedora (or similar). See linfo.org/daemon.html .
Have a look at start-stop-daemon in Debian ; I will leave here a related thread from stack overflow stackoverflow.com/questions/16139940/… which is more interesting than the raw man page
2 Answers 2
In a Unix environment, the parent process of a daemon is often, but not always, the init process. A daemon is usually either created by a process forking a child process and then immediately exiting, thus causing init to adopt the child process, or by the init process directly launching the daemon. In addition, a daemon launched by forking and exiting typically must perform other operations, such as dissociating the process from any controlling terminal (tty). Such procedures are often implemented in various convenience routines such as daemon(3) in Unix.
Read the manpage of the daemon function.
Running a background command from a shell that immediately exits results in the process's PPID becoming 1. Easy to test:
# bash -c 'nohup sleep 10000 &>/dev/null & jobs -p %1' 1936 # ps -p 1936 PID PPID PGID WINPID TTY UID STIME COMMAND 1936 1 9104 9552 cons0 1009 17:28:12 /usr/bin/sleep
As you can see, the process is owned by PID 1, but still associated with a TTY. If I log out from this login shell, then log in again, and do ps again, the TTY becomes ? .
Using setsid (part of util-linux ):
# bash -c 'cd /; setsid sleep 10000 /dev/null & jobs -p %1' 9864 # ps -p 9864 PID PPID PGID WINPID TTY UID STIME COMMAND 9864 1 9864 6632 ? 1009 17:40:35 /usr/bin/sleep
I think you don't even have to redirect stdin, stdout and stderr.
Запуск приложения в режиме “daemon” в Linux
Часто случается ситуация, что нужно запустить приложение в Linux, которое не должно быть завершено при выходе пользователя, а режима демона у приложения нет.
На этот случай можно воспользоваться парой приемов.
Первый способ
Запустить в сессии программы screen, которая не завершается при выходе пользователя.
использованные параметры:
-d -m – Запустить новый сеанс screen, но не подключаться к нему.
Так же можно использовать параметр:
-S имя – задать имя сессии screen для удобства поиска сессии по имени.
Пример:
screen -d -m -S backgroud_ping ping 127.0.0.1
Эта команда запустит пинг адреса 127.0.0.1 и присвоит сессии имя backgroud_ping.
Для возврата к приложению и получению управления нужно:
посмотреть список активный сессий screen:
в выводе консоли мы увидим имя и PID процесса:
There is a screen on:
1218.backgroud_ping (13.05.2016 15:43:34) (Detached)
1 Socket in /var/run/screen/S-root.
запущенная сессия будет иметь имя backgroud_ping, и в данном случае, PID будет 1218.
теперь остается подключиться к процессу screen, это делается командой:
Мы получили обратно управление над приложением.
Второй способ
Использовать утилиту nohup, которая запустит приложение с игнорированием сигналов потери связи (SIGHUP), что позволит продолжить выполнение приложения после выхода пользователя из системы.
вывод будет перенаправлен вместо консоли в файл nohup.out, который будет находиться в папке из которой производился запуск. Посмотреть вывод консоли можно командой:
В данном случае вернуться к приложению и получить управление нельзя. его можно только завершить командой kill.
Третий способ
Использовать утилиту start-stop-daemon, которая создана для запуска в фоне приложений, которые сами не умеют переходить в фон.
start-stop-daemon -S -b -x путь_и_имя_исполняемого_файла -m -p путь_и_имя_pid_файла
использованные параметры:
-S – запустить;
-b – запустить в фоне;
-x – полный путь и имя исполняемого файла;
-m – создать PID-файл с номером процесса;
-p – путь и имя PID-файла.
Если требуется запустить программу с параметрами, то параметры указываются в конце, после двойного тире (подробнее – в примере).
start-stop-daemon -S -b -x /bin/ping -m -v -p /run/ping.pid -- -I eth0 127.0.0.1
В данном примере мы запускаем утилиту ping с параметрами (-I eth0 127.0.0.1) и создаем PID-файл (/run/ping.pid).
Для остановки программы использутся другие параметры:
start-stop-daemon -K -x путь_и_имя_исполняемого_файла
start-stop-daemon -K -p путь_и_имя_pid_файла
использованные параметры:
-K – остановить;
-x – найти по имени запущенной программы;
-p – найти по PID-файлу .
start-stop-daemon -K -p /run/ping.pid
Находим номер процесса, записанный в файл /run/ping.pid и останавливаем его.
Более правильно всегда использовать PID-файлы, потому что имя запускаемой программы не всегда равно имени запущенного процесса.
Заказать создание и поддержку безопасной IT-инфраструктуры любой сложности
Быть уверенным в своей IT-инфраструктуре – это быть уверенным в завтрашнем дне.
"Proper" way to run shell script as a daemon
I am writing a shell script that I would like to run as a daemon on startup without using external tools like daemontools or daemonize.
Linux Daemon Writing HOWTO
- forks from the parent process
- closes all file descriptors (i.e., stdin , stdout , stderr )
- opens logs for writing (if configured)
- changes the working directory to one that is persistent (usually / )
- resets the file mode mask (umask)
- creates an unique Session ID (SID)
daemonize Introduction
The daemonize Introduction goes further, stating that a typical daemon also:
- disassociates from its control terminal (if there is one) and ignores all terminal signals
- disassociates from its process group
- handles SIGCLD
How would I do all this in a sh , dash , or bash script with common Linux tools only?
The script should be able to run on as many distros as possible without additional software, although Debian is our primary focus.
NOTE: I know there are plenty of answers on the StackExchange network recommending the use of nohup or setsid , but neither of these methods tackles all of the requirements above.
EDIT: The daemon(7) manpage also gives some pointers, although there seem to be some differences between older-style SysV daemons and newer systemd ones. Since compatibility with a variety of distros is important, please ensure the answer makes clear any differences.