web-dev-qa-db-ja.com

Ubuntuの起動時にサービスを自動的に開始するにはどうすればよいですか?

Ubuntu 12.04を使用していて、システムが正常に起動したときにサービスを開始したい。

「サービス」として、たとえばcd my_directoryなどのコードを理解しています。 my_command -Host 0.0.0.0 -port 1234 -arg xコマンドラインで開始されたかのように実行されている必要があります。通常のユーザーとして開始するサービスがありますが、rootとして開始するサービスもあります(実際、ユーザーレベルで実行する必要はありません)。

「サービス」が停止したときの動作も設定する必要があります。私の場合、同じ引数を使用して、指定したディレクトリで再起動してほしい。

システムが正常に起動したとき、つまり電源スイッチが押されたときに、すべてのサービスが自動的に開始されます。他のアクションは必要ありません。

インターネット上にはいくつかの文書が広まっていますが、それらはすべて私を混乱させます。彼らはinitinit.drc.dについて話しますが、次のように簡単に実行できるステップバイステップの指示を、サービスとして簡単に実行する方法を見たことはありません。新興。これが簡単な場合は、それらの手順をここに示していただければ幸いです。

32
Alex

Ubuntuの起動時に自動的に開始されるジョブを作成するには、 here の例を使用します。記述例として、Sudoを使用して次のファイル/etc/init/testservice.confを作成するとします。

# testservice - test service job file

description "my service description"
author "Me <[email protected]>"

# 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

ジョブ制御コマンド を参照してください。

34
Alex

さて、アレックス、要点は、Linuxのすべてのユーザースペースプロセスは、pidが1であるinitプロセスで開始されるということです。たとえば、pstreeを実行して、ルートを持つプロセスのツリーを表示しますis init ..最近、initプロセス実装にはいくつかのバージョンがあり、最も注目すべきは

  • sysVinit(古いinit、古いDebianを含む一部のディストリビューションでまだ使用されています)
  • 古いUbuntuと一部のRHEL(Red Hat)および古いFedoraバージョンで使用されるUpstart init
  • systemd init、最新のFedora、Ubuntu、Debian、RHEL、SUSEバージョンで使用

従来、UnixはsysVinit initと呼ばれるinit実装を使用し、 https://ru.wikipedia.org/wiki/UNIX_System_V バージョンのUnixの名前で呼ばれていました。それは非常に影響力があり、他のinitはそれに下位互換性があります。

基本的に、sysVinitは最初に_/etc/inittab_ファイルを読み取り、実行するランレベルを決定し、いわゆるinitスクリプトを実行するように_/etc/init.d/rc_スクリプトに通知します。例えば。通常 buntuのランレベル2 であるマルチユーザーランレベルで起動すると、_/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_で始まり、次にSSまたはKの後の2桁は00から99までの数字で、プロセスが開始される順序を決定します。 rsyslogは_Apache2_の前に開始されます。これは、16が17未満であるためです(つまり、Apacheがrsyslogのログ容量に依存するようにするため、最初にrsyslogを開始する必要があります)。スクリプトは、_#!/bin/sh_によって実行されるカジュアルなシェルスクリプトです。

したがって、基本的には、起動時にsysVinitスタイルでプログラムを起動するには、独自のスクリプトを記述し(任意の例からコピーして貼り付け、_/etc/init.d_に入っている)、_/etc/init.d_に配置してシンボリックリンクを作成します。それに適切な名前で、例えば_S99mytrojan_の_/etc/rc2.d_。 /etc/init.d内の一般的なsysVinitスクリプトの説明はこちらです http://docs.Oracle.com/cd/E19683-01/806-4073/6jd67r96g/index.html

今、Ubuntuの人たちは、initに追加の機能が必要だと判断しました。彼らは高速起動OSを望んでいたので、スクリプトを並行して実行したかったのです。彼らは、死んだプロセスが自動的に再起動されることを望んでいました。彼らは、プロセスがイベントによって明示的に相互に呼び出すことを望んでいました(Apacheは「syslog started」イベントによって実行され、syslogは「ファイルシステムがマウントされた」イベントによって実行されるなど)。 -99)。したがって、彼らはUpstartを作成し、 here はそれがどのように機能するかです。 Upstart initscriptsは_/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 network up」のグーグルを試してください。

23
Boris Burkov