Linux run process as service

How can I make an executable run as a service?

On Ubuntu 18.04, I can start or stop some service by

I can list some services by

The output matches the files under /etc/init.d/ .

I heard there are several ways of managing services: system V init, systemd, upstart, . Which one am I using? man service shows it is system V init. But I heard that Linux replaces init with systemd. Shall I use systemd instead of init on Ubuntu?

How can I make an arbitrary executable file (either ELF or shell script) become a service?

Do I need to explicitly daemonize the executable by setsid , like https://stackoverflow.com/a/19235243/156458?

Does any of the post below apply to me?

2 Answers 2

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

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.

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?

This question is unclear.

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:

Читайте также:  Когда выйдет windows 10 1607

Store this unit under /etc/systemd/system/foo.service , then reload systemd to read this unit file with:

Start the service with:

And enable it during startup with:

You can check the status of the service with:

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.)

Does any of the post below apply to me?

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.

Источник

Как создать свой сервис для Linux

Несмотря на большое количество проблем и ненависть некоторых пользователей, systemd уже стал стандартом де-факто во многих дистрибутивах Linux. С его помощью из десяток строк настроек можно за несколько минут создать несложный процесс . В то же время многие более интересные возможности документированы не очень понятным языком или требуют углубленных познаний в тонкостях работы systemd.

Основы создания сервиса Linux

Если вы еще никогда не делали свои сервисы, начнем с основ. Systemd оперирует абстрактными единицами (unit), которые бывают разных типов, могут предоставлять различные ресурсы (процессы, сокеты, абстрактные «цели») и требовать других ресурсов для запуска.

Самый распространенный вид ресурса — сервис (service). Файлы с описаниями сервисов и всего прочего лежат в каталоге /lib/systemd/system/ . Чтобы systemd нашел новый сервис, достаточно положить в этот каталог свой файл. Если этот сервис ранее не существовал, systemd прочитает файл и загрузит его в память. Однако, если вы редактируете файл ранее запущенного сервиса, не забудьте заставить systemd перечитать файлы командой sudo systemctl daemon-reload !

Сервисы типа oneshot — долой rc.local

Когда-то основным способом добавить выполнение команд в загрузку системы было дописать их в /etc/rc.local. Очевидный недостаток — нет способов следить, насколько успешно они выполнились. В systemd легко создать для такой цели свой сервис типа oneshot, и им можно будет управлять через systemctl, как любым другим. В этом случае systemd выполнит команду и посчитает запуск сервиса успешным, если она завершилась с кодом ноль.

Сохраним следующий файл в /lib/systemd/system/dumb-test.service :

Дополнительных действий не требуется, и теперь вы можеыр делать с ним все то же, что с системными сервисами: запустить с помощью sudo systemctl start dumb-test.service , поставить на загрузку с помощью sudo systemctl enable dumb-test.service и так далее.

Читайте также:  Как отключить гиперсон windows 10

Создание сервиса из любой программы

Любой долгоживущий процесс можно легко превратить в сервис с помощью опции Type=idle . В этом случае systemd перехватит стандартные потоки ввода-вывода и будет следить за жизнью процесса.

Для демонстрации напишем программу на Python, которая просто выводит сообщение в бесконечном цикле. Сохраним в /usr/local/bin/test.py следующее:

Затем создадим для нее файл сервиса в /lib/systemd/system/smart-test.service :

Теперь можно запустить наш сервис и убедиться, что он работает:

Стандартный вывод программы пишется в journald, и его можно увидеть в journalctl -u smart-test . Ради интереса посмотрим на работу опции Restart=on-failure . Остановим наш процесс с помощью kill -9 $

и заглянем в логи:

Для настоящих демонов нужно использовать тип forking , но мы не будем вдаваться в детали — авторы таких пакетов наверняка все уже знают сами.

Зависимости и порядок запуска

Опций для настройки зависимости в systemd очень много. Прежде всего нужно отметить, что в нем есть два независимых механизма для указания порядка запуска сервисов и зависимостей между ними.

Порядок запуска сервисов

Порядок запуска сервисов определяется опциями Before и After . Если в настройках сервиса foo написано After=bar.service и оба сервиса должны запуститься, то systemd сначала выполнит попытку запустить bar, а затем foo.

Однако опция After=bar.service сама по себе не поставит сервис на загрузку. Более того, она никак не повлияет на решение запускать foo, даже если запуск bar завершится неудачей.

Причина существования этих опций — способность systemd запускать сервисы параллельно.

Для примера возьмем типичный веб-сервер с набором из веб-приложения FCGI, СУБД и обратного прокси. В каком порядке запускать процесс FCGI и обратный прокси, не так важно. Запросы будут работать, только когда они оба запущены, но «неверный порядок» никак не помешает им запуститься.

Если веб-приложение требует данных из базы для инициализации, то мало убедиться, что и процесс FCGI, и СУБД запущены, — приложение нужно запускать только после полного запуска СУБД. Именно для этих случаев и предназначены опции Before/After .

Зависимости

Зависимости бывают двух видов: мягкие и жесткие. Если оба сервиса запустились успешно, то никакой разницы между ними нет. Различие вступает в действие, если один из сервисов не смог запуститься: если зависимость мягкая, то зависимые сервисы все равно будут запущены, а если жесткая, то systemd не станет даже пробовать их запустить.

Мягкие зависимости указываются с помощью опции Wants= в секции [Unit] . Пример из sshd.service :

Цель sshd-keygen.target , очевидно, генерирует ключ хоста, если он отсутствует. Технически sshd не сможет запуститься без ключа хоста, поэтому, почему авторы решили сделать зависимость мягкой, можно только догадываться. Возможно, они посчитали, что в большинстве случаев ключ уже существует и устаревший ключ лучше неработающего SSH.

При копировании настроек из пакетов дистрибутива нужно быть осторожным. Разработчики дистрибутивов тоже люди и вполне могут создавать неоптимальные или ошибочные конфигурации. Кроме того, если что-то работает для одного сервиса, совсем не факт, что оно же подойдет для другого, так что сверяйтесь с документацией и тестируйте перед выпуском.

Жесткие зависимости можно указать с помощью опции Requires . К примеру, в systemd-journal-flush.service есть опция Requires=systemd-journald.service — очевидно, отправить команду journald невозможно, пока он не запущен.

У этой опции существуют вариации, например RequiresMountsFor . Посмотрим в файл logrotate.service :

Для работы logrotate нужен доступ к каталогу с логами и больше ничего. Опция RequiresMountsFor=/var/log позволяет выразить именно это: сервис запустится, как только будет примонтирован каталог, содержащий путь /var/log , даже если он находится не в корневом разделе.

Читайте также:  Oscar editor windows 10 что это

Внедрение в зависимости к чужим сервисам

В системах с System V init добавить что-то в зависимости к чужому сервису можно было, лишь отредактировав его скрипт. Такие изменения, очевидно, не переживут обновления системы, поэтому сделать их постоянными можно было бы только пересборкой пакета.

В systemd есть несколько способов решить эту проблему. Если нужно именно внедриться к кому-то в зависимости, можно попробовать опции обратных зависимостей: WantedBy и RequiredBy . Они должны находиться в секции [Install] , а не [Unit] . Подводных камня здесь два: они обрабатываются только при установке сервиса с помощью systemctl enable и, как все в systemd, не всегда нормально работают во всех версиях.

Второй вариант, который позволяет менять любые настройки: скопировать файл сервиса в /etc/systemd/system/ . Если один файл присутствует в обоих каталогах, то файл из /etc/systemd/system имеет приоритет.

Источник

Setup a python script as a service through systemctl/systemd

There are several ways you can run your program as a background service in Linux such as crontab, .bashrc, etc but today I’ll write about systemd. I was initially looking for a way to run my python script as a background service so even if the server restarts for some reason, my script will run in the background regardless and I found that systemd allows me to do that. Let’s get started

I’ll be setting this up on an Ubuntu 18.10 machine.

Almost all versions of Linux come with systemd out of the box, but if your’s didn’t come with it then you can simply run the following command:

Note: The -y flag means to install the packages and dependencies quickly.

To check which version of systemd you have simply run the command:

Create a python file whatever you like. I’m going to call mine test.py.

sudo nano test.py

The above script will write the current timestamp in the file after every 10 seconds. Let’s write the service now.

sudo nano /etc/systemd/system/test.service (name of the service which is test in this case)

Insert the username in your OS where is written. The ExecStart flag takes in the command that you want to run. So basically the first argument is the python path (in my case it’s python3) and the second argument is the path to the script that needs to be executed. Restart flag is set to always because I want to restart my service if the server gets restarted. For more information on this, you can go to this link. Now we need to reload the daemon.

Let’s enable our service so that it doesn’t get disabled if the server restarts.

And now let’ start our service.

Now our service is up and running.

Note: The file will be written in the root directory (/) because the program will write in the path from the perspective of systemd. To change that simply edit out the file path. For example:

There are several commands you can do to start, stop, restart, and check status.

To stop the service.

To check status.

This was a very basic introduction to systemd aimed at beginners who want to get started with writing their own systemd services for python. If you want a deep dive into systemd and systemctl, here is a detailed guide by the digital ocean.

NOTE: This doesn’t only apply to python scripts. You can basically run any program with this regardless of the programming language your program is written in.

Источник

Оцените статью