Как запустить сервис автоматически при запуске Ubuntu?

31

Я использую Ubuntu 12.04 и хочу, чтобы служба запускалась, когда система загружается нормально.

Под «сервисом» я понимаю некоторый код, например, cd my_directory; my_command -host 0.0.0.0 -port 1234 -arg x, который просто должен быть запущен, как если бы он был запущен в командной строке. Есть службы, которые должны быть запущены как обычный пользователь, но также и службы, которые должны быть запущены как root (на самом деле, службы не должны запускаться на уровне пользователя).

Мне также требуется настроить поведение, когда «служба» останавливается. Я хочу, чтобы они были перезапущены в моем случае с тем же аргументом в указанном каталоге.

Все службы должны запускаться автоматически при нормальном запуске системы, т. Е. При нажатии выключателя питания. Никаких других действий не требуется.

В Интернете есть несколько документов, но все они меня смущают. Они не говорить о том init, init.d, rc.d, но я никогда не видел простой в последующей шаг за шагом инструкции легко в качестве службы с использованием , например , выскочка. Если это легко, я был бы признателен, если бы эти шаги были приведены здесь.

Alex
источник

Ответы:

33

Чтобы создать задание, которое будет запускаться автоматически при запуске Ubuntu, используйте приведенный здесь пример . В качестве написанного примера предположим, что для создания следующего файла /etc/init/testservice.confс sudo:

# testservice - test service job file

description "my service description"
author "Me <myself@i.com>"

# Stanzas
#
# Stanzas control when and how a process is started and stopped
# See a list of stanzas here: http://upstart.ubuntu.com/wiki/Stanzas

# When to start the service
start on runlevel [2345]

# When to stop the service
stop on runlevel [016]

# Automatically restart process if crashed
respawn

# Essentially lets upstart know the process will detach itself to the background
# This option does not seem to be of great importance, so it does not need to be set.
#expect fork

# Specify working directory
chdir /home/user/testcode

# Specify the process/command to start, e.g.
exec python mycommand.py arg1 arg2

Чтобы «вручную» запустить или остановить процесс использования

sudo start testservice
sudo stop testservice

Смотрите команды управления заданиями .

Alex
источник
Мне нужно было "начать с запущенного mountall", чтобы запустить сервис.
martinedwards
23

Хорошо, Алекс, дело в том, что все процессы пользовательского пространства в Linux запускаются с initпроцессом, pid которого равен 1. Например, запустите, pstreeчтобы увидеть дерево ваших процессов, корень которого - init. В настоящее время существует несколько версий initреализации процесса. наиболее заметными являются

  • sysVinit (классический init, до сих пор используется в некоторых дистрибутивах, включая старый Debian)
  • Upstart init, используемый более старой Ubuntu и некоторыми RHEL (Red Hat) и более ранними версиями Fedora
  • systemd init, используемый в современных версиях Fedora, Ubuntu, Debian, RHEL, SUSE

Традиционно Unix'ы использовали реализацию sysVinitinit, называемую init, называемую по имени https://ru.wikipedia.org/wiki/UNIX_System_V версии Unix. Это очень влиятельно, и другие объекты обратно совместимы с ним.

По сути, sysVinit сначала читает /etc/inittabфайл, решает, какой уровень запуска запускать, и указывает /etc/init.d/rcсценарию выполнять так называемые сценарии инициализации. Например, когда он обычно загружается с многопользовательского уровня запуска, который обычно является уровнем запуска 2 в Ubuntu , /etc/init.d/rcначинает выполнять сценарии в /etc/rc2.d. В файлах есть только символические ссылки на скрипты, а сами скрипты хранятся в /etc/init.dкаталоге. Наименование этих символических ссылок в /etc/rc*.dкаталогах выглядит следующим образом. Скажем, у нас есть следующие скрипты /etc/rc2.d:

$ls /etc/rc2.d
S16rsyslog
S17apache2
K02network-manager

Это означает, что при переходе на уровень запуска 2 процесс init сначала убивает network-managerпроцессы, потому что его имя сценария начинается с K-, K02network-managerа затем запускает процессы, чьи имена начинаются с S. Две цифры после Sили K- это число от 00 до 99, которое определяет порядок, в котором запускаются процессы. Например rsyslog, запускается раньше apache2, потому что 16 меньше 17 (это имеет смысл, потому что вы хотите, чтобы apache полагался на возможности ведения журнала rsyslog , таким образом, rsyslog должен быть запущен первым). Скрипты являются случайными скриптами оболочки, выполняемыми #!/bin/sh.

Итак, чтобы запустить программу при запуске в стиле sysVinit, напишите свой собственный скрипт (скопируйте его из любого примера, который у вас есть /etc/init.d), поместите его /etc/init.dи создайте символическую ссылку на него под разумным именем, например, S99mytrojanв /etc/rc2.d. Вот объяснение типичных скриптов sysVinit в /etc/init.d http://docs.oracle.com/cd/E19683-01/806-4073/6jd67r96g/index.html

Теперь ребята из Ubuntu решили, что они хотят получить дополнительную функциональность от init. Они хотели бы иметь быструю загрузку ОС, поэтому они хотели, чтобы их скрипты выполнялись параллельно; они хотели, чтобы мертвые процессы были автоматически перезапущены; они хотели, чтобы процессы вызывали друг друга явным образом по событиям (чтобы apache запускался событием «syslog начался», а syslog запускался событием «смонтированные файловые системы» и т. д., поэтому у нас есть события вместо некоторых чисел 00) -99). Таким образом, они сделали Upstart и вот как это работает. Начальные скрипты выскочки помещаются в /etc/initкаталог (не путайте с /etc/init.d). Upstart обычно /etc/init.d/rcтоже запускается , поэтому он будет нормально выполнять ваши скрипты sysVinit. Но если вы хотите, чтобы ваш скрипт появлялся при выходе - события Upstart для вас.

Хотя я не могу проверить, работает ли мой скрипт, я полагаю, что для ваших целей вы должны написать следующий /etc/init/mytrojan.confскрипт:

start on runlevel [02]
respawn
exec mytrojan --argument X 

Но если вам нужны зависимости, по крайней мере, файловые системы и сеть, возможно, имеет смысл заменить start on runlevel [02]что-то вроде:

start on (local-filesystems and net-device-up IFACE!=lo)

ВНИМАНИЕ: я не проверял правильность этого, потому что я не могу. В частности, я не совсем уверен, как запустить скрипт после того, как ваше сетевое соединение запущено (я использовал эту версию ). Попробуйте прибегнуть к помощи "upstart on up сети".

Борис Бурков
источник
1
Это очень хороший обзор истории процесса, запущенного в Linux, но он не дает ответа на вопрос. Я до сих пор не знаю, как «создать» процесс выскочки. Я также просто хочу использовать его, а не понимать, как это работает. Я просто хотел иметь простой и удобный в использовании рабочий пример того, как создать процесс, который будет запускаться и автоматически вызываться с помощью upstart ubuntu..l.
Алекс
@Alex: обновлено с помощью образца scipt. Обратите внимание, что мой сценарий вполне может быть неправильным. Я сделал это в духе alexreisner.com/code/upstart .
Борис Бурков
1
Проголосовал, потому что это один из лучших ответов, которые я когда-либо читал.
user1301428