ดำเนินการคำสั่งก่อนที่จะปิด / รีบูต [ซ้ำ]


18

ฉันมีเครื่องที่ใช้ VM คนจรจัดสองคน ปัญหาที่ฉันมีคือบางครั้งฉันลืมที่จะปิด VM เหล่านั้นก่อนที่ฉันจะปิดหรือรีบูตเครื่องของฉัน เนื่องจากเครื่องของฉันติดกับข้อความนี้:waiting for vboxnet0 to become free

ฉันค้นหาเกี่ยวกับวิธีแก้ไขปัญหาและพบหน้านี้:

http://en.kioskea.net/faq/3348-ubuntu-executing-a-script-at-startup-and-shutdown

ฉันลองสิ่งที่พวกเขาปิด แต่มันไม่ทำงาน

ฉันเขียนไฟล์ sh สำหรับคำสั่งนั้น:

#!/bin/bash

cd ~/workspace/git/mediaservice
vagrant halt

ข้อเสนอแนะใด ๆ


4
วิธีการในลิงค์นั้นใช้ได้และทำงานกับทุกเวอร์ชั่นของ linux ดังนั้นสคริปต์ของคุณผิด;) ผู้ใช้ไม่รู้จักเมื่อปิดระบบเนื่องจากมันทำโดยผู้ใช้รูท ดังนั้นวาง "~" และทำให้เป็นเส้นทางที่เต็ม
Rinzwind

ใช้งานได้หรือไม่ ฉันติดตามมานูเอลที่คล้ายกันเช่นgist.github.com/ymc-geha/8416723แต่ไม่ได้ผลสำหรับฉันบน Ubuntu 14.04
user2135804

@ user2135804 ฉันคิดว่ามันทำ .. แต่จริงๆแล้วมันไม่ได้ผลสำหรับ Vagrant .. ฉันลองกับสิ่งอื่น ๆ และใช้งานได้ดี
SERPRO

1
โดยวิธีการที่ข้อผิดพลาดที่คุณอธิบายเป็นที่นี่
Garrett

1
ดังที่เห็นในรายงานข้อผิดพลาดสิ่งนี้ได้รับการแก้ไขแล้วและจะรวมอยู่ใน VirtualBox 4.3.29
Garrett

คำตอบ:


11

หาก VM ของคนจรจัดของคุณกำลังใช้ VirtualBox คุณสามารถแก้ไข / etc / default / virtualbox และเปลี่ยนบรรทัดที่อ่าน:

SHUTDOWN_USERS=""

ถึง

SHUTDOWN_USERS="all"

ที่แก้ไขมันสำหรับฉันบน Ubuntu 14.04


1
จริงๆแล้วมีตั๋วเปิดในกล่องเสมือนที่เชื่อมต่อกับสิ่งนี้ virtualbox.org/ticket/12264 ฉันจะแนะนำให้ใช้SHUTDOWN_USERS=`cut -d: -f1 /etc/passwd`แทนSHUTDOWN_USERS="all"
running.t

ฉันยังบน Ubuntu 14.04 กับคนจรจัดใช้ VirtualBox แต่ฉันไม่ได้มี/etc/default/virtualboxไฟล์ ...
การ์เร็ต

21

ในการรันสคริปต์เมื่อปิดเครื่องหรือรีบูต:

  1. บันทึกสคริปต์ของคุณใน /etc/rc6.d
  2. ทำให้ปฏิบัติการได้: sudo chmod +x K99_script

หมายเหตุ:

  • สคริปต์ใน rc6.d จะต้องไม่มีนามสกุล. sh
  • ชื่อสคริปต์ของคุณจะต้องเริ่มต้นด้วย K99 เพื่อให้ทำงานได้ในเวลาที่เหมาะสม
  • สคริปต์ในไดเรกทอรีนี้จะทำงานตามลำดับตัวอักษร

แหล่ง


1
จริง การตั้งชื่ออย่างถูกต้องเพื่อให้ทำงานในเวลาที่เหมาะสมมีความสำคัญมาก
shivams

1
ฉันใส่สคริปต์ใน / etc / rc6.d และมันไม่ได้ทำงานเมื่อปิด ฉันวางไว้ใน / etc / rc0.d และมันก็ทำงานเมื่อปิดเครื่อง อาจเป็นไปได้ว่า rc.6 สำหรับรีบูตเท่านั้น
Erel Segal-Halevi

2
@Erel Segal-Halevi ฉันเพิ่งลองเพิ่มสคริปต์ K99 ไปยัง /etc/rc6.d และไม่ได้ทำงาน เมื่อมองไปที่สคริปต์อื่น ๆ จะมีบรรทัดตัวหนา ** K10reboot -> ../init.d/reboot ** ดังนั้นดูเหมือนว่าสคริปต์ K99 จะไม่ถูกเรียกใช้ !!
David Walker

คำตอบจาก Ravi ด้านล่างเป็นตัวเลือกที่ดีกว่าเนื่องจากใช้ symlink เพื่อให้แน่ใจว่าสคริปต์ทำงานได้ทั้งในการปิดระบบและรีบูต ฉันคิดว่าไฟล์ระบบส่วนใหญ่มักจะใช้วิธีนี้
Eddie

12

วิธีทำด้วย Systemd (ง่ายกว่า)

ตอนนี้ตัวแปร Ubuntu และมิ้นท์ได้ย้ายไปที่ systemd ฉันพบวิธีแก้ไขปัญหาเก่าของฉันตามที่กล่าวไว้ข้างต้นเป็นที่น่าพอใจน้อยลง ฉันค้นหาในเว็บเพื่อค้นหาวิธีใช้ systemd และลงเอยด้วยการรวมภูมิปัญญาของผู้อื่นและบันทึกไว้เป็นโพสต์บล็อกที่blogspot.com.auซึ่งมีบทช่วยสอนต่อไปนี้

ด้วย systemd คุณสามารถสร้างไฟล์หนึ่งหรือสองไฟล์เพื่อเรียกใช้สคริปต์ของคุณโดยใช้เทมเพลตด้านล่างและดำเนินการคำสั่งสองสามคำสั่ง ง่าย


เวอร์ชัน GUI

ขั้นแรกให้สร้างสคริปต์ที่คุณต้องการเรียกใช้เมื่อเริ่มต้นและ / หรือปิดระบบ ทำอย่างใดอย่างหนึ่งถ้าคุณไม่ต้องการทั้ง ฉันสร้าง. scopening_atstart และ. scfullcopy_atend

จากนั้นตรวจสอบให้แน่ใจว่าไฟล์ทั้งสองนั้นสามารถเรียกใช้งานได้โดยคลิกขวาที่ไฟล์เลือกคุณสมบัติและตรวจสอบให้แน่ใจว่าภายใต้การอนุญาตคุณได้ทำเครื่องหมายที่อนุญาตให้เรียกใช้ไฟล์ปฏิบัติการเป็นโปรแกรม

ป้อนคำอธิบายรูปภาพที่นี่

สองไฟล์ที่ฉันสร้างเติมและบันทึกเนื้อหาของ ramdisk พวกเขายังสร้างไฟล์ในโฮมไดเร็กตอรี่ของฉันเพื่อพิสูจน์ว่าบริการใช้งานได้ พวกเขาอยู่ในรูปแบบ:

#!/bin/sh
cp -pru /home/john/zRamdisk/subdirectory1/* /home/john/.wine/drive_c/subdirectory1/
rm /home/john/stop_time
date +%D' '%T > /home/john/stop_time

จากนั้นฉันก็เปิดตัวจัดการไฟล์ในฐานะรูทเปิด/etc/systemd/systemและสร้างไฟล์ startup.service และไฟล์ save-ramdisk.service เห็นได้ชัดว่าคุณสามารถเลือกชื่อของคุณเองและชื่อทั่วไปอาจรวมถึงไฟล์เริ่มต้นที่ชื่อ johns_start.service และไฟล์ปิดที่ชื่อ johns_shutdown.service อย่าเลือกชื่อบริการที่มีอยู่

[Unit]
Description=Startup Applications

[Service]
Type=oneshot
RemainAfterExit=false
ExecStart=/home/john/.scopening_atstart

[Install]
WantedBy=multi-user.target

และ

[Unit]
Description=Save Ramdisk to Wine drive C

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=/home/john/.scfullcopy_atend

[Install]
WantedBy=multi-user.target

คุณสามารถใช้ไฟล์บริการเดียวกันแทนที่เส้นทางแบบเต็มของสคริปต์ที่เรียกใช้งานได้ของฉัน

ในที่สุดสำหรับแต่ละคนดำเนินการคำสั่ง systemctl เปิดใช้งาน your_files_name (แต่ไม่มีบริการต่อท้าย) ดังนั้นอันแรกของฉันคือsystemctl enable startup

รีบูทคอมพิวเตอร์หนึ่งครั้งเพื่อเริ่มบริการ บริการเริ่มต้นจะถูกดำเนินการเมื่อใดก็ตามที่ systemd เข้าสู่เป้าหมายผู้ใช้หลายคนและบริการหยุดเมื่อออกจากเป้าหมายผู้ใช้หลายคน ไฟล์บริการทางเลือกที่มีเงื่อนไขการเปิดใช้งานแตกต่างกันจะอธิบายไว้ด้านล่าง

คำสั่งที่มีประโยชน์เพิ่มเติม ได้แก่ :

systemctl is-enabled startup,
systemctl is-startup startup
systemctl ทำการรีสตาร์ท

สามารถดูเพิ่มเติมได้ที่การอ้างอิงข้างต้น



เวอร์ชันของ CLI (Command Line)

คำอธิบายนี้อนุมานว่าคุณทำงานจากโฮมไดเร็กตอรี่ของคุณแทนที่จะเป็น / home / john, ใช้ sudo ตามต้องการ, และตัวเลือกของบรรณาธิการที่ฉันเขียนเป็นกลุ่มหรือ svim

สร้างเชลล์สคริปต์เริ่มทำงานและปิดระบบด้วยบรรทัดแรก#!/bin/shและทำให้สามารถใช้งานchmod +x my_new_filenameได้

สร้างสองไฟล์ดังกล่าวข้างต้นหรือในตัวอย่างนี้หนึ่งไฟล์เพื่อจัดการงานเริ่มต้นและปิด ผมจะรันสคริปต์ในไดเรกทอรีบ้านของฉัน แต่ @don_crissti แสดงให้เห็นทางเลือกบางอย่างที่กองแลกเปลี่ยน

svim /etc/systemd/system/start_and_stop.service

และคัดลอกในเนื้อหาไฟล์:

[Unit]
Description=Run Scripts at Start and Stop

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/home/john/.startup_commands  #your paths and filenames
ExecStop=/home/john/.shutdown_commands

[Install]
WantedBy=multi-user.target

จากนั้นเปิดใช้งานบริการด้วยคำสั่ง:

systemctl enable start_and_stop

และรีบูตระบบของคุณหลังจากที่บริการจะเปิดใช้งาน คำสั่งsystemctl is-enabled start_and_stopและsystemctl is-active start_and_stopสามารถใช้ในการตรวจสอบบริการใหม่ของคุณ



การเปลี่ยนเงื่อนไข Trigger สำหรับการปิดเครื่อง

ไฟล์ข้างต้นทั้งหมดใช้การเปิดหรือปิดของสภาพแวดล้อมที่มีผู้ใช้หลายคนเพื่อเริ่มการทำงานของสคริปต์ ไฟล์ด้านล่างใช้การเริ่มต้นกระบวนการปิดที่อาจเกิดขึ้นสี่ขั้นตอนเพื่อเริ่มต้นสคริปต์ การเพิ่มหรือลบเป้าหมายในบรรทัด Before + บรรทัด WantedBy จะช่วยให้คุณสร้างความแตกต่างที่ละเอียดยิ่งขึ้น:

ไฟล์นี้มีการเสนอในคำตอบที่สองของโพสต์นี้แต่ฉันไม่สามารถให้มันทำงานจนกว่าฉันจะเพิ่มส่วนการติดตั้ง

อีกครั้งแก้ไขสคริปต์ในและเปิดใช้งานได้โดยใช้/etc/systemd/service/ systemctl enable your_file_nameเมื่อฉันเปลี่ยนเป้าหมายฉันใช้systemclt disable file_nameคำสั่งและเปิดใช้งานอีกครั้งซึ่ง symlinked ไปยังไดเรกทอรีเป้าหมาย รีบูทและบริการจะทำงาน

[Unit]
Description=Do something required
DefaultDependencies=no
Before=shutdown.target reboot.target halt.target
# This works because it is installed in the target and will be
#   executed before the target state is entered
# Also consider kexec.target

[Service]
Type=oneshot
ExecStart=/home/john/.my_script  #your path and filename

[Install]
WantedBy=halt.target reboot.target shutdown.target

7
ง่ายขึ้น? ง่ายกว่าอะไร ง่ายกว่าการปีนเขาเอเวอเรสต์? วิธีแก้ปัญหาอื่น ๆ ทั้งหมดที่โพสต์ที่นี่ง่ายกว่าโซลูชันนี้ ...
Fran Marzoa

ว้าวนั่นเป็นคำตอบที่สมบูรณ์และเป็นลายลักษณ์อักษรอย่างเหมาะสมและสิ่งที่ทุกคนควรทำ - ปัญหาการตั้งชื่อของ /etc/rc6.d และความสับสนบ่งบอกว่านั่นไม่ใช่คำตอบที่ดี หากขั้นตอนนั้นง่ายแสดงว่าไม่จำเป็นต้องมีอำนาจในการบรรลุจุดจบอย่างปลอดภัย ดูส่วน [ติดตั้ง] - คุณมั่นใจได้ว่าสคริปต์ของคุณจะทำงานในเวลาที่ถูกต้อง นอกจากนี้เนื่องจากคำตอบยาวนั่นไม่ได้หมายความว่ามันซับซ้อน! ขอบคุณ btw, John9631 คำตอบนี้สมบูรณ์แบบและจะประเมินค่าไม่ได้ในการสร้างสคริปต์ที่ปลอดภัยและมีประสิทธิภาพ ณ จุดวิกฤติภารกิจในเวลา ...
มิลเลอร์กอริลลา

11
  1. สร้างไฟล์เรียกทำงานเชลล์ด้วยสคริปต์ของคุณในไดเรกทอรี /etc/init.d/

  2. ตั้งแต่นี้จะต้องมีการดำเนินการในระหว่างการปิดเครื่องหรือรีบูตจำเป็นต้องสร้างซอฟต์ลิงค์ใน /etc/rc0.d/ และ /etc/rc6.d

ตัวอย่าง:

sudo ln -s /etc/init.d/<your_file> /etc/rc0.d/k99stop_vm
sudo ln -s /etc/init.d/<your_file> /etc/rc6.d/k99stop_vm
sudo chmod a+x /etc/init.d/<your_file>

chmodเปลี่ยนค่าสถานะการอนุญาตของเป้าหมายลิงก์ซึ่งเหมือนกันสำหรับทั้งสองอาร์กิวเมนต์ การระบุทั้งสองอย่างนั้นซ้ำซ้อน
David Foerster

2

คุณสามารถหาวิธีการแก้ปัญหาที่นี่: ระงับ / ประวัติกล่องจรจัดทั้งหมดในการปิดระบบ

มีสคริปต์เริ่มต้นง่ายๆที่หยุดการทำงานของกล่องทั้งหมดก่อนที่จะปิดตัวลง

การติดตั้ง

แก้ไข/etc/init.d/vagrant-boxesและวางสคริปต์จากบทความด้านบนและบันทึก หรือดาวน์โหลดได้จากที่นี่/etc/init.d/vagrant-boxesและบันทึกลงใน บนเดเบียน / อูบุนตู ฯลฯ ให้เรียกใช้

# update-rc.d vagrant-boxes defaults 99 01

หมายเลข 99 คือหมายเลขลำดับและควรมีขนาดใหญ่กว่า (ในกรณีของฉัน Virtualbox หมายเลข 20 ซึ่งเป็นค่าเริ่มต้นของ Debian distros) หมายเลขที่สองคือลำดับเมื่อปิดเครื่องคอมพิวเตอร์ ดังนั้นมันอาจเป็นการดีที่จะทำก่อนอื่น


2

สำหรับ Ubuntu 14.10 บางสิ่งที่คุณRC04ไม่ชอบRC99

สิ่งที่ต้องทำตั้งแต่เริ่มต้น

  1. สร้างสคริปต์ที่ /etc/init.d/scriptName
  2. ลิงค์ผ่าน ln -s /etc/rc6.d/K04scriptName /etc/init.d/scriptName

ขั้นตอนที่ฉันผ่าน

  1. ฉันพยายามใช้ไม่สำเร็จ Ubuntu - การเรียกใช้สคริปต์เมื่อเริ่มต้นและปิดระบบ
  2. ฉันพบสคริปต์การปิดอูบุนตู 14.10 ด้วย rc0.d (rc6.d, rc.d)
  3. ฉันเปลี่ยนจาก /etc/rc6.d/RC99linkName เป็น /etc/rc6.d/RC04linkName และใช้งานได้
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.