好的,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
init的init实现,其名称为Unix 的https://ru.wikipedia.org/wiki/UNIX_System_V版本。它非常有影响力,其他实例都向后兼容。
基本上,sysVinit首先读取/etc/inittab
文件,确定要运行的运行级别,并告诉/etc/init.d/rc
脚本执行所谓的初始化脚本。例如,当它通常启动到多用户运行级别(通常在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
或后面的两位数字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 http://docs.oracle.com/cd/E19683-01/806-4073/6jd67r96g/index.html中的典型sysVinit脚本的解释。
现在,Ubuntu家伙决定他们要从init获得更多功能。他们想要一个快速启动的OS,因此希望它们的脚本可以并行执行。他们希望死进程自动重新启动;他们希望进程通过事件以显式方式相互调用(以便apache由“ syslog启动”事件运行,而syslog由“文件系统安装”事件运行,等等,因此我们拥有事件而不是某些数字00 -99)。因此,他们创造了Upstart,这就是它的工作方式。新贵的初始化脚本放在/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)
警告:我没有检查它的正确性,因为我做不到。特别是,我不太确定如何在网络连接建立并运行后如何启动脚本(我使用了此版本)。尝试搜索“网络启动新贵”。