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 initquy 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 initthự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à sysVinitinit, đượ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/inittabtệp, quyết định, runlevel sẽ chạy và yêu cầu /etc/init.d/rctậ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/rcbắ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.dthư mục. Việc đặt tên của các liên kết tượng trưng trong các /etc/rc*.dthư 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-managercác tiến trình, khiến tên tập lệnh của nó bắt đầu bằng K- K02network-managervà sau đó bắt đầu các tiến trình, có tên bắt đầu bằng S. Hai chữ số sau Shoặc Klà 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.dvà 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ư
S99mytrojantrong /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/initthư mục (đừng nhầm lẫn với /etc/init.d). Upstart thường chạy /etc/init.d/rcquá, 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.confkị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".