จะเริ่มบริการอัตโนมัติอย่างไรเมื่อ Ubuntu เริ่มทำงาน


31

ฉันใช้ Ubuntu 12.04 และต้องการเริ่มบริการเมื่อระบบบู๊ตตามปกติ

ในฐานะ 'บริการ' ฉันเข้าใจรหัสบางอย่างเช่น cd my_directory; my_command -host 0.0.0.0 -port 1234 -arg x ที่ควรรันราวกับว่ามันถูกสตาร์ทในบรรทัดคำสั่ง มีบริการที่จะเริ่มต้นเป็นผู้ใช้ปกติ แต่ยังมีบริการที่จะเริ่มต้นเป็นรูท

ฉันต้องกำหนดค่าลักษณะการทำงานเมื่อหยุด 'บริการ' ฉันต้องการให้พวกเขาเริ่มต้นใหม่ในกรณีของฉันด้วยอาร์กิวเมนต์เดียวกันในไดเรกทอรีที่ระบุ

บริการทั้งหมดควรเริ่มต้นโดยอัตโนมัติเมื่อระบบเริ่มต้นตามปกติคือหากกดสวิตช์ไฟ ไม่ควรดำเนินการอื่น ๆ

มีเอกสารบางส่วนแพร่กระจายบนอินเทอร์เน็ต แต่พวกเขาทั้งหมดทำให้ฉันสับสน พวกเขาพูดคุยเกี่ยวกับinit, init.d, rc.dแต่ฉันไม่เคยเห็นการเรียนการสอนที่ง่ายต่อการปฏิบัติตามขั้นตอนโดยขั้นตอนได้อย่างง่ายดายเป็นบริการที่ใช้เช่นพุ่งพรวด ถ้านี่เป็นเรื่องง่ายฉันจะขอบคุณถ้าทำตามขั้นตอนเหล่านี้ที่นี่

คำตอบ:


33

ในการสร้างงานที่จะเริ่มต้นโดยอัตโนมัติเมื่ออูบุนตูเริ่มต้นใช้ตัวอย่างที่ให้ไว้ที่นี่ ตามตัวอย่างที่เป็นลายลักษณ์อักษรสมมติว่าสร้างไฟล์ต่อไปนี้/etc/init/testservice.confด้วย 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

หากต้องการ 'ด้วยตนเอง' ให้เริ่มหรือหยุดการใช้กระบวนการ

sudo start testservice
sudo stop testservice

ดูคำสั่งควบคุมงาน


ฉันต้องการ "start on start mountall" เพื่อเริ่มบริการ
martinedwards

23

ตกลงอเล็กซ์ประเด็นก็คือกระบวนการ userspace ทั้งหมดใน Linux เริ่มต้นด้วยinitโพรเซสซึ่ง pid คือ 1 ตัวอย่างเช่นเรียกใช้pstreeเพื่อดูแผนผังกระบวนการของคุณซึ่งรูทเป็นรากเริ่มต้น .. initกระบวนการปรับใช้กระบวนการมีหลายรุ่นในปัจจุบัน สิ่งที่น่าสังเกตมากที่สุดคือ

  • sysVinit (คลาสสิก init ยังคงใช้โดยการแจกแจงบางอย่างรวมถึง Debian ที่เก่ากว่า)
  • พุ่งพรวด init ใช้โดย Ubuntu รุ่นเก่าและรุ่น RHEL (Red Hat) และ Fedora รุ่นเก่าบางรุ่น
  • systemd init ใช้โดย Fedora รุ่นใหม่, Ubuntu, Debian, RHEL, SUSE version

ตามเนื้อผ้า Unix'es ใช้การใช้งาน init เรียกว่าsysVinitinit เรียกโดยชื่อhttps://ru.wikipedia.org/wiki/UNIX_System_Vเวอร์ชัน Unix มันมีอิทธิพลมากและ inits อื่น ๆ จะย้อนกลับเข้ากันได้กับมัน

โดยทั่วไป sysVinit ก่อนจะอ่าน/etc/inittabไฟล์ตัดสินใจซึ่ง runlevel เพื่อรันและบอก/etc/init.d/rcสคริปต์ให้เรียกใช้สคริปต์ init ที่เรียกว่า เช่นเมื่อมันปกติรองเท้ากับระดับการทำงานแบบ multi-user ซึ่งมักจะrunlevel 2 บน Ubuntu , เริ่มดำเนินการในสคริปต์/etc/init.d/rc /etc/rc2.dไฟล์มีลิงก์เชิงสัญลักษณ์ไปยังสคริปต์เท่านั้นในขณะที่สคริปต์จะถูกเก็บไว้ใน/etc/init.dไดเรกทอรี การตั้งชื่อ symlink เหล่านั้นใน/etc/rc*.dไดเรกทอรีมีดังนี้ บอกว่าเรามีสคริปต์ต่อไปนี้ใน/etc/rc2.d:

$ls /etc/rc2.d
S16rsyslog
S17apache2
K02network-manager

มันหมายถึงว่าเมื่อเปลี่ยนไปใช้กระบวนการ runlevel init 2 ครั้งแรกฆ่าnetwork-managerกระบวนการสาเหตุเริ่มต้นชื่อสคริปต์ด้วยK- และจากนั้นก็เริ่มกระบวนการที่มีชื่อขึ้นต้นด้วยK02network-manager SตัวเลขสองหลักหลังSหรือKเป็นตัวเลขตั้งแต่ 00 ถึง 99 ซึ่งเป็นตัวกำหนดลำดับกระบวนการเริ่มต้นขึ้นเช่นrsyslogเริ่มต้นก่อนapache2เพราะ 16 น้อยกว่า 17 (ที่เหมาะสมแล้วทำให้คุณต้องการอาปาเช่ขึ้นอยู่กับความสามารถในการบันทึกของ rsyslog ดังนั้น rsyslog ควรเริ่มต้นก่อน) สคริปต์สคริปต์เปลือกลำลอง, #!/bin/shดำเนินการโดย

ดังนั้นโดยทั่วไปจะเริ่มต้นโปรแกรมเมื่อเริ่มต้นในรูปแบบ sysvinit เขียนสคริปต์ของคุณเอง (คัดลอกวางจากตัวอย่างใด ๆ ที่คุณได้รับใน/etc/init.d) นำไปใช้/etc/init.dและสร้าง symlink ไปมันภายใต้ชื่อที่เหมาะสมเช่น ในS99mytrojan /etc/rc2.dนี่คือคำอธิบายของสคริปต์ sysVinit ทั่วไปใน /etc/init.d http://docs.oracle.com/cd/E19683-01/806-4073/6jd67r96g/index.html

ตอนนี้พวก Ubuntu ตัดสินใจว่าพวกเขาต้องการฟังก์ชั่นเพิ่มเติมจาก init พวกเขาต้องการระบบปฏิบัติการบูทที่รวดเร็วดังนั้นพวกเขาจึงต้องการให้สคริปต์ของพวกเขาทำงานแบบขนาน พวกเขาต้องการให้กระบวนการที่ตายแล้วเริ่มต้นใหม่โดยอัตโนมัติ พวกเขาต้องการกระบวนการที่จะเรียกกันอย่างชัดเจนโดยเหตุการณ์ (เพื่อให้ Apache ทำงานโดยเหตุการณ์ "syslog เริ่มต้น" และ syslog ดำเนินการโดยเหตุการณ์ "ติดตั้งระบบไฟล์" ฯลฯ ดังนั้นเราจึงมีเหตุการณ์แทนตัวเลขบางตัว 00 -99) ดังนั้นพวกเขาจึงทำ Upstart และนี่คือวิธีการทำงาน Initscripts พุ่งพรวดจะถูกวางใน/etc/initไดเรกทอรี (อย่าสับสนกับ/etc/init.d) การพุ่งพรวดมักจะทำงาน/etc/init.d/rcด้วยเช่นกันดังนั้นจึงจะดำเนินการกับสคริปต์ sysVinit ของคุณตามปกติ แต่ถ้าคุณต้องการให้สคริปต์ของคุณเกิดขึ้นอีกครั้งเมื่อออก - เหตุการณ์เริ่มต้นสำหรับคุณ

แม้ว่าฉันจะไม่สามารถตรวจสอบได้ว่าสคริปต์ของฉันทำงานได้ แต่ฉันคิดว่าสำหรับจุดประสงค์ของคุณคุณควรเขียน/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)

คำเตือน: ฉันไม่ได้ตรวจสอบความถูกต้องของสิ่งนี้เพราะฉันไม่สามารถ โดยเฉพาะอย่างยิ่งฉันไม่แน่ใจเกี่ยวกับวิธีการเริ่มต้นสคริปต์หลังจากการเชื่อมต่อเครือข่ายของคุณทำงานแล้ว (ฉันใช้รุ่นนี้ ) ลองใช้ googling เพื่อ "พุ่งพรวดบนเครือข่ายขึ้น"


1
นี่เป็นภาพรวมที่ดีมากเกี่ยวกับประวัติความเป็นมาของกระบวนการที่เริ่มต้นใน Linux แต่ไม่ตอบคำถาม ฉันยังไม่รู้วิธีการ 'สร้าง' กระบวนการพุ่งพรวด ฉันแค่อยากจะใช้มันไม่เข้าใจเลยว่ามันทำงานอย่างไร ฉันแค่อยากจะมีตัวอย่างการทำงานที่ง่ายและใช้งานง่ายของวิธีการสร้างกระบวนการที่จะเริ่มต้นและเกิดขึ้นใหม่โดยอัตโนมัติด้วยการพุ่งพรวดของอูบุนตู ..
Alex

@Alex: อัปเดตพร้อมกับตัวอย่างตัวอย่าง โปรดทราบว่าสคริปต์ของฉันอาจผิดไปมาก ฉันไม่ได้ในจิตวิญญาณของalexreisner.com/code/upstart
Boris Burkov

1
โหวตขึ้นเพราะนี่คือหนึ่งในคำตอบที่ดีที่สุดที่ฉันเคยอ่าน
user1301428
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.