Làm thế nào để bắt đầu một dịch vụ tự động, khi Ubuntu khởi động?


31

Tôi đang sử dụng Ubuntu 12.04 và muốn có một dịch vụ bắt đầu, khi hệ thống được khởi động bình thường.

Là 'dịch vụ' Tôi hiểu một số mã, ví dụ cd my_directory; my_command -host 0.0.0.0 -port 1234 -arg x chỉ nên chạy như thể nó đã được bắt đầu trên dòng lệnh. Có những dịch vụ được bắt đầu như người dùng bình thường, nhưng cũng có những dịch vụ được bắt đầu với quyền root (thực tế, không bắt buộc dịch vụ phải được chạy ở cấp độ người dùng).

Tôi cũng yêu cầu định cấu hình hành vi khi 'dịch vụ' dừng. Tôi muốn chúng được khởi động lại trong trường hợp của tôi, với cùng một đối số, trong một thư mục được chỉ định.

Tất cả các dịch vụ nên được khởi động tự động khi hệ thống khởi động bình thường, tức là nếu nhấn công tắc nguồn. Không có hành động khác nên được yêu cầu.

Có một số tài liệu lan truyền trên internet, nhưng tất cả đều làm tôi bối rối. Họ nói chuyện về init, init.d, rc.d, nhưng tôi chưa bao giờ thấy một bước-by-step hướng dẫn đơn giản-để-sau để dễ dàng như một dịch vụ sử dụng ví dụ mới nổi. Nếu điều này là dễ dàng, tôi sẽ đánh giá cao nếu những bước đó được đưa ra ở đây.

Câu trả lời:


33

Để tạo một công việc được bắt đầu tự động khi Ubuntu khởi động, hãy sử dụng ví dụ được đưa ra ở đây . Như ví dụ bằng văn bản, giả sử tạo tệp sau /etc/init/testservice.confbằng sudo:

# 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

Để 'thủ công' bắt đầu hoặc dừng quá trình sử dụng

sudo start testservice
sudo stop testservice

Xem các lệnh điều khiển công việc .


Tôi cần "bắt đầu khi bắt đầu mountall" để bắt đầu dịch vụ.
martinedwards

23

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".


1
Đây là một tổng quan rất hay về lịch sử của quá trình bắt đầu trong Linux, nhưng nó không trả lời bằng câu hỏi. Tôi vẫn không biết cách 'tạo' một quy trình mới. Tôi cũng chỉ muốn sử dụng nó, không hiểu từng chút một về cách hoạt động của nó. Tôi chỉ muốn có một ví dụ hoạt động đơn giản và dễ sử dụng, về cách tạo một quy trình để được bắt đầu và tự động trả lời với phần khởi động của ub Ubuntu..l.
Alex

@Alex: được cập nhật với một scipt mẫu. Lưu ý rằng kịch bản của tôi rất có thể sai. Tôi đã làm nó theo tinh thần của alexreisner.com/code/upstart .
Boris Burkov

1
Ủng hộ vì đây là một trong những câu trả lời hay nhất tôi từng đọc.
dùng1301428
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.