จะเริ่มบริการอัตโนมัติอย่างไรเมื่อ 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.