How to run a program as a service (silent)?
I have a python based server which i start from the terminal. This particular instance of the terminal then gives control to the program, and the program uses it as a kind of logging window, until its closed. Is this normal, or should i somehow try to start the program some other way in which it will simply show as an active process? If i close the terminal from which i started the program, the program dies with it. Thank you
PHP is mentioned in this answer but it applies to Python, too: askubuntu.com/questions/26555/running-php-cli-server/…
5 Answers 5
Turn it to a daemon (service)
daemon —name=»yourservicename» —output=log.txt sh yourscript.sh
Even old bash is using & for sending processes to background, but there is few other ways too .. but basic two are these :
1.)$~ your_command > outputfile_for_stdout & # runs your command in background, giving you only PID so you can exit that process by `kill -9 PID_of_process` # & goes at the end of row 2.)$~ your_command > outputfile_for_stdout # this will run your program normally # press Ctrl + Z then program will pause $~ bg # now your program is running in background $~ fg # now your program came back to foreground 3.)you can run terminal window under screen command so it will live until you either kill it or you reboot your machine $~ screen $~ run_all_your_commands # Ctrl + A + D will then detach this screen $~ screen -r will reattach it
Some other useful commands :
$~ jobs # will show you all processes running right now, but without PID $~ ps # will show you all processes for actual terminal window
Запуск Python скрипта в виде службы через systemctl/systemd
Есть несколько способов запуска вашей программы в качестве фоновой службы в Linux, таких как crontab, .bashrc и т. д., но сегодня будет разговор о systemd. Изначально я искал способ запустить свой скрипт на Python в качестве фоновой службы, поэтому даже если сервер по какой-то причине перезагрузится, мой скрипт все равно должен работать в фоновом режиме, после небольшого ресерча и я обнаружил, что systemd позволяет мне это сделать. Давайте начнем.
Настройки далее будут производиться на машине с Ubuntu 20.04.
Почти все версии Linux поставляются с systemd из коробки, но если у вас его нет, вы можете просто запустить следующую команду:
sudo apt install -y systemd
Примечание. Флаг -y означает быструю установку пакетов и зависимостей.
Чтобы проверить, какая версия systemd у вас установлена, просто выполните команду:
Создайте файл python с любым именем. Я назову свой скрипт именем test.py.
import time from datetime import datetime while True: with open("timestamp.txt", "a") as f: f.write("Текущая временная метка: " + str(datetime.now())) f.close() time.sleep(10)
Приведенный выше скрипт будет записывать текущую метку времени в файл каждые 10 секунд. Теперь напишем сервис.
sudo nano /etc/systemd/system/test.service
(имя службы, которая тестируется в этом случае)
[Unit] Description=My test service After=multi-user.target [Service] User=deepak Group=admin Type=simple Restart=always ExecStart=/usr/bin/python3 /home//test.py [Install] WantedBy=multi-user.target
Замените имя пользователя в вашей ОС, где написано . Флаг ExecStart принимает команду, которую вы хотите запустить. Таким образом, в основном первый аргумент — это путь к python (в моем случае это python3), а второй аргумент — это путь к скрипту, который необходимо выполнить. Флаг перезапуска всегда установлен, потому что я хочу перезапустить свою службу, если сервер будет перезапущен.
Здесь мы определили User=deepak и Group=admin, чтобы убедиться, что скрипт будет выполняться только от имени пользователя deepak, входящего в группу admin.
Теперь нам нужно перезагрузить демон.
sudo systemctl daemon-reload
Давайте включим наш сервис, чтобы он не отключался при перезагрузке сервера.
sudo systemctl enable test.service
А теперь давайте запустим наш сервис.
sudo systemctl start test.service
Теперь наш сервис работает.
Примечание. Файл будет записан в корневой каталог (/), потому что программа запишет путь с точки зрения systemd. Чтобы изменить это, просто отредактируйте путь к файлу. Например:
import time from datetime import datetime path_to_file = "введите желаемый путь к файлу" while True: with open(path_to_file, "a") as f: f.write("Текущая временная метка: " + str(datetime.now())) f.close() time.sleep(10)
Есть несколько команд, которые вы можете выполнить для запуска, остановки, перезапуска и проверки состояния.
sudo systemctl stop name_of_your_service
sudo systemctl restart name_of_your_service
sudo systemctl status name_of_your_service
Это было очень поверхностное знакомство с systemd, предназначенное для новичков, которые хотят начать писать свои собственные systemd службы для python.
ПРИМЕЧАНИЕ. Это относится не только к сценариям Python. Вы можете запустить любую программу с ним, независимо от языка программирования, на котором написана ваша программа.
How can I make an executable run as a service?
Ubuntu 18.04 uses systemd. The scripts in /etc/init.d are only used if a systemd unit file does not exist for the service. It is preferable that systemd services do not daemonize.
You have 2 questions here, and the answer to one does not necessarily dictate the answer to the other. A linux OS may have multiple daemon managers.
2 Answers 2
On Ubuntu 18.04, [. ]
I heard there are several ways of managing services: system V init, systemd, upstart, . Which one am I using?
You’re using systemd, that’s the init that’s shipped on Ubuntu 18.04. (Also on Ubuntu 16.04, on Fedora, on openSUSE, on Arch Linux, on RHEL 7, on CentOS 7, on CoreOS, and it’s also the default on Debian 9.)
One good way to confirm that you’re running systemd is to run the command systemctl . If it’s available and it produces output when run, then you’re running systemd.
On Ubuntu 18.04, I can start or stop some service by
sudo service cron start/stop
I can list some services by
Please note that the service command shipped in some systemd distros is there mostly for backward compatibility. You should try to manage services using systemctl instead.
$ sudo systemctl start cron $ sudo systemctl stop cron $ systemctl status cron
And you can find status of all units with a simple
The output matches the files under /etc/init.d/ .
That’s not necessarily the case with systemctl , since systemd native units are stored in /etc/systemd/system/ and /usr/lib/systemd/system/ .
systemd does include compatibility with old SysV init scripts (through systemd-sysv-generator, which creates a systemd native service unit calling the commands from the init script), so if you have init scripts under /etc/init.d/ , they’ll most likely show up in systemd as well.
Shall I use systemd instead of init on Ubuntu?
The term init generally refers to the first process run when the system boots, the process run with PID 1. systemd runs with PID 1, so by definition systemd is an init (and so was upstart before it, and SysV init as well.)
If you’re asking «should I use systemd instead of SysV init?», well then you’re already using systemd instead of SysV init, since you’re on Ubuntu 18.04. (And, as pointed out above, most distributions you’d pick these days would most likely include systemd as their init.)
Now, you could be asking «should I use systemd units instead of init scripts?» and that question is more relevant, since arguably you have a choice here where both options will work.
My recommendation here is that you should manage services using systemd units, which is the native mode of operation. Creating an init script simply adds a layer of indirection (since the generator will just create a systemd unit for you anyways.) Furthermore, writing systemd units is simpler than writing init scripts, since you don’t have to worry about properly daemonizing and scrubbing the environment before execution, since systemd does all that for you.
How can I make an arbitrary executable file (either ELF or shell script) become a service?
See the examples on the man page. The simplest example shows how easy it can be to create a service unit:
[Unit] Description=Foo [Service] ExecStart=/usr/sbin/foo-daemon [Install] WantedBy=multi-user.target
Store this unit under /etc/systemd/system/foo.service , then reload systemd to read this unit file with:
$ sudo systemctl daemon-reload
$ sudo systemctl start foo.service
And enable it during startup with:
$ sudo systemctl enable foo.service
You can check the status of the service with:
$ systemctl status foo.service
Of course, systemd can do a lot more for you to manage services, so a typical systemd unit will be longer than this one (though not necessarily that much more complex.) Browse the units shipped with Ubuntu under /usr/lib/systemd/system/*.service to get a better picture of what’s typical, of what to expect.
No! Don’t run in background, don’t worry about process groups or sessions, etc. systemd takes care of all that for you. Just write your code to run in foreground and systemd will take care of the rest.
(If you have a service that runs in background, systemd can manage it, with Type=forking , but things are much easier when just running in foreground, so just do that if you’re starting a new service.)
This one is about applications using the «Spring Boot» Java framework. Unless you’re writing Java code and using that framework, it’s not relevant. If you’re writing Java code, try instead to just run your service in foreground instead.
The question is about upstart, the answer is about SysV init scripts. While SysV init scripts will work with systemd, it’s preferable that you write systemd units directly, as mentioned above.
So, no, I’d say neither of those are relevant.
I’d recommend trying to learn more about systemd service units instead.
This site is also a great resource for that, so feel free to post more questions about it as you explore writing your own systemd units for your services.