Ok, Alex, vấn đề là tất cả các quy trình không gian người dùng trong Linux đều được bắt đầu bằng init
quy trình, có pid là 1. Ví dụ, hãy chạy pstree
để xem cây quy trình của bạn, có root là init .. Hiện tại có một số phiên bản init
thực hiện quy trình , đáng chú ý nhất là
- sysVinit (init cổ điển, vẫn được sử dụng bởi một số bản phân phối, bao gồm cả Debian cũ)
- Khởi đầu init, được sử dụng bởi Ubuntu cũ và một số phiên bản RHEL (Red Hat) và Fedora cũ hơn
- init systemd, được sử dụng bởi các phiên bản Fedora, Ubuntu, Debian, RHEL, SUSE hiện đại
Theo truyền thống, Unix đã sử dụng triển khai init được gọi là sysVinit
init, được gọi bằng tên của https://ru.wikipedia.org/wiki/UNIX_System_V phiên bản Unix. Nó rất có ảnh hưởng và các loại mực khác tương thích ngược với nó.
Về cơ bản, sysVinit trước tiên đọc /etc/inittab
tệp, quyết định, runlevel sẽ chạy và yêu cầu /etc/init.d/rc
tập lệnh thực thi cái gọi là init script. Ví dụ: khi nó thường khởi động một runlevel nhiều người dùng, thường là runlevel 2 trên Ubuntu , /etc/init.d/rc
bắt đầu thực thi các tập lệnh trong /etc/rc2.d
. Các tập tin chỉ có các liên kết tượng trưng đến các tập lệnh, trong khi các tập lệnh được lưu trữ trong /etc/init.d
thư mục. Việc đặt tên của các liên kết tượng trưng trong các /etc/rc*.d
thư mục như sau. Nói rằng, chúng tôi đã có các kịch bản sau đây trong /etc/rc2.d
:
$ls /etc/rc2.d
S16rsyslog
S17apache2
K02network-manager
Điều đó có nghĩa là, khi chuyển sang runlevel 2 init process, đầu tiên sẽ giết network-manager
các tiến trình, khiến tên tập lệnh của nó bắt đầu bằng K
- K02network-manager
và sau đó bắt đầu các tiến trình, có tên bắt đầu bằng S
. Hai chữ số sau S
hoặc K
là số từ 00 đến 99, xác định thứ tự, các quy trình được bắt đầu. Ví dụ: rsyslog
được bắt đầu trước apache2
, bởi vì 16 nhỏ hơn 17 (điều đó có nghĩa, khiến bạn muốn apache dựa vào khả năng ghi nhật ký của rsyslog , do đó rsyslog nên được bắt đầu trước). Các kịch bản là các kịch bản shell thông thường, được thực hiện bởi #!/bin/sh
.
Vì vậy, về cơ bản để bắt đầu một chương trình khi khởi động theo kiểu sysVinit, hãy viết tập lệnh của riêng bạn (sao chép nó từ bất kỳ ví dụ nào bạn đã tham gia /etc/init.d
), đặt nó vào /etc/init.d
và tạo một liên kết tượng trưng cho nó dưới một tên hợp lý, ví dụ như
S99mytrojan
trong /etc/rc2.d
. Dưới đây là giải thích về các tập lệnh sysVinit điển hình trong /etc/init.d http://docs.oracle.com/cd/E19683-01/806-4073/6jd67r96g/index.html
Bây giờ, những người Ubuntu đã quyết định rằng họ muốn có thêm chức năng từ init. Họ muốn có một hệ điều hành khởi động nhanh, vì vậy họ muốn các tập lệnh của họ được thực thi song song; họ muốn các quy trình chết được tự động khởi động lại; họ muốn các quá trình gọi nhau theo cách rõ ràng bằng các sự kiện (để apache được điều hành bởi sự kiện "syslog started" và syslog được điều hành bởi sự kiện "tập tin gắn kết", v.v., vì vậy chúng tôi có các sự kiện thay vì một số số 00 -99). Vì vậy, họ đã thực hiện Upstart và đây là cách nó hoạt động. Initsartts mới bắt đầu được đặt trong /etc/init
thư mục (đừng nhầm lẫn với /etc/init.d
). Upstart thường chạy /etc/init.d/rc
quá, vì vậy nó sẽ thực thi các tập lệnh sysVinit của bạn một cách bình thường. Nhưng nếu bạn muốn tập lệnh của mình được đáp ứng khi thoát - các sự kiện khởi động là dành cho bạn.
Mặc dù tôi không thể kiểm tra xem tập lệnh của mình có hoạt động hay không, tôi cho rằng, vì mục đích của bạn, bạn nên viết /etc/init/mytrojan.conf
kịch bản sau :
start on runlevel [02]
respawn
exec mytrojan --argument X
Nhưng nếu bạn cần phụ thuộc, ít nhất là hệ thống tập tin và mạng, có thể nên thay thế start on runlevel [02]
bằng một cái gì đó như:
start on (local-filesystems and net-device-up IFACE!=lo)
CẢNH BÁO: Tôi đã không kiểm tra tính chính xác của điều này, vì tôi không thể. Đặc biệt, tôi không chắc lắm về cách khởi động tập lệnh sau khi kết nối mạng của bạn hoạt động (Tôi đã sử dụng phiên bản này ). Hãy thử googling cho "khởi động trên mạng lên".