我使用的是 Ubuntu 12.04,希望在系统正常启动时启动一个服务。
作为“服务”,我理解一些代码,例如 cd my_directory; my_command -host 0.0.0.0 -port 1234 -arg x 应该像在命令行上启动一样运行。有以普通用户启动的服务,也有以 root 身份启动的服务(实际上,并不要求服务必须在用户级别运行)。
我还需要配置“服务”停止时的行为。我希望它们在我的情况下使用相同的参数在指定的目录中重新启动。
当系统正常启动时,即按下电源开关时,所有服务都应自动启动。不需要采取其他行动。
网上流传着一些文件,但它们都让我感到困惑。他们谈论init
,,,但我从未见过简单易懂的分步说明,可以轻松地使用例如新贵作为服务init.d
。rc.d
如果这很容易,如果这里给出这些步骤,我将不胜感激。
答案1
要创建一个在 Ubuntu 启动时自动启动的作业,请使用给出的示例这里。作为书面示例,假设/etc/init/testservice.conf
使用 sudo创建以下文件:
# 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
请参阅作业控制命令。
答案2
好吧,Alex,重点是 Linux 中的所有用户空间进程都是以init
process 启动的,其 pid 为 1。例如,运行pstree
查看进程树,其根为 init。init
现在有多个版本的进程实现,最值得注意的是
- sysVinit(经典的 init,仍然被一些发行版使用,包括较旧的 Debian)
- Upstart init,由较旧的 Ubuntu 和一些 RHEL (Red Hat) 以及较旧的 Fedora 版本使用
- systemd init,由现代 Fedora、Ubuntu、Debian、RHEL、SUSE 版本使用
传统上,Unix 使用名为 init 的 init 实现sysVinit
,其名称为https://ru.wikipedia.org/wiki/UNIX_System_VUnix 版本。它的影响力非常大,并且其他 init 都向后兼容它。
基本上,sysVinit 首先读取/etc/inittab
文件,决定运行哪个运行级别,并告诉/etc/init.d/rc
脚本执行所谓的 init 脚本。例如,当它正常启动到多用户运行级别时,通常是Ubuntu 上的运行级别 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
,然后启动名称以 开头的进程S
。S
or后面的两位数字K
是从 00 到 99 的数字,它决定了进程启动的顺序。例如,rsyslog
在 之前启动apache2
,因为 16 小于 17 (这是有道理的,因为你希望 apache 依赖 rsyslog 的日志记录能力,因此应首先启动 rsyslog)。这些脚本是临时 shell 脚本,由#!/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 的附加功能。他们想要一个快速启动的操作系统,因此他们希望他们的脚本能够并行执行;他们希望死进程能够自动重新启动;他们希望进程通过事件以显式方式相互调用(以便apache由“syslog启动”事件运行,syslog由“文件系统安装”事件运行等,所以我们有事件而不是一些数字00 -99)。因此,他们创造了 Upstart 并这里就是它的工作原理。 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)
警告:我没有检查其正确性,因为我不能。特别是,我不太确定如何在网络连接启动并运行后启动脚本(我使用过这个版本)。尝试用谷歌搜索“网络上的新贵”。