问题描述
我正在使用Ubuntu 12.04,并希望在正常启动系统时启动服务。
作为’service’,我了解一些代码,例如cd my_directory;。 my_command -host 0.0.0.0 -port 1234 -arg x刚好应该像在命令行上启动一样运行。有的服务要以普通用户身份启动,也有的服务要以root用户身份启动(实际上,不需要在用户级别上运行服务)。
我还需要配置’service’停止时的行为。我希望使用相同的参数在指定目录中重新启动它们。
当系统正常启动时,即按下电源开关时,所有服务应自动启动。无需采取其他措施。
互联网上散布着一些文件,但它们都使我感到困惑。他们谈论的是init
,init.d
,rc.d
,但我从未见过simple-to-follow step-by-step指令可以轻松地作为服务使用,例如暴发户。如果这很容易,请在此给出这些步骤。
最佳答案
要创建在Ubuntu启动时自动启动的作业,请使用给出的示例here。作为书面示例,假设使用sudo创建以下文件/etc/init/testservice.conf
:
# 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
要’manually’启动或停止使用
sudo start testservice
sudo stop testservice
次佳答案
好的,Alex,关键是要在Linux中所有用户空间进程都以init进程(其pid为1)启动。例如,运行pstree来查看根为init的进程树。.init有多种版本如今,流程实施最为明显
-
sysVinit(经典init,仍在某些发行版中使用,包括较旧的Debian)
-
Upstart初始化,由较旧的Ubuntu和某些RHEL(Red Hat)和较旧的Fedora版本使用
-
systemd init,由现代Fedora,Ubuntu,Debian,RHEL,SUSE版本使用
传统上,Unix使用的初始化实现称为sysVinit
初始化,其名称为Unix的https://ru.wikipedia.org/wiki/UNIX_System_V版本。它非常有影响力,其他实例都向后兼容。
基本上,sysVinit首先读取/etc/inittab
文件,确定要运行的运行级别,并告诉/etc/init.d/rc
脚本执行so-called初始化脚本。例如。当正常启动到multi-user运行级别(通常为runlevel 2 on 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初始化进程时,首先会杀死network-manager
进程,导致其脚本名称以K
–K02network-manager
开头,然后启动其名称以S
开头的进程。 S
或K
后面的两位数字是从00到99的数字,它确定了顺序,过程开始于此。 rsyslog
在apache2
之前启动,因为16小于17(这很有意义,因为您希望Apache依赖rsyslog的日志记录容量,因此应先启动rsyslog)。脚本是由#!/bin/sh
执行的临时shell脚本。
因此,基本上是要在启动时以sysVinit样式启动程序,编写自己的脚本(从任何示例中获取它的copy-pasting,您已经在/etc/init.d
中获得),将其放入/etc/init.d
并以合理的名称创建指向其的符号链接,例如/etc/rc2.d
中的S99mytrojan
。这是/etc/init.d中典型sysVinit脚本的说明http://docs.oracle.com/cd/E19683-01/806-4073/6jd67r96g/index.html
现在,Ubuntu家伙决定他们想要从init获得更多功能。他们想要一个快速启动的OS,因此希望它们的脚本可以并行执行。他们希望死进程自动重启;他们希望进程通过事件以显式方式相互调用(以便apache由”syslog started”事件运行,而syslog由“文件系统安装”事件运行,等等,因此我们拥有事件,而不是数字00-99) 。因此,他们创造了Upstart,而here是它的工作方式。新贵的初始化脚本放在/etc/init
目录中(不要与/etc/init.d
混淆)。新贵通常也运行/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)
警告:我没有检查它的正确性,因为我做不到。特别是,我不太确定如何在网络连接建立并运行后如何启动脚本(我使用了this version)。尝试搜索“网络启动新贵”。