เรียกใช้งานสคริปต์เมื่อออกจากระบบ / รีบูต / ปิดระบบใน Ubuntu


30

ฉันต้องการเรียกใช้.shไฟล์โดยใช้ bash เมื่อล็อกเอาต์และปิดตัว Ubuntu ฉันค้นหาเว็บขึ้นและลงและพบเฉพาะการแก้ไขสำหรับ KDE และ GNOME สคริปต์นั้นง่ายฉันแค่ต้องรู้ว่าฉันสามารถเพิ่มบรรทัดของรหัสไปยังแฟ้ม "logoff / shutdown" หรือถ้าฉันต้องการอ้างอิงในสคริปต์อื่น


1
ใส่ symlink ไปยัง executables ใน /etc/init.d ใน /etc/rc0.d และ /etc/rc6.d
แต่ผู้ใช้คนอื่น

2
โปรดพิจารณายอมรับคำตอบที่ปรับปรุงแล้ว (โดยใช้systemd) เพื่อให้คนอื่นเห็นมันอยู่ด้านบน
โจนาธานวาย

คำตอบ:


18

วิธีรันสคริปต์เมื่อออกจากระบบ:

เพิ่มบรรทัดต่อไปนี้:

session-cleanup-script=/path/to/script

ใน/etc/lightdm/lightdm.confไฟล์

คุณต้องรีสตาร์ท lightdm เพื่อให้การเปลี่ยนแปลงนี้มีผล ในการทำสิ่งนี้ให้ไปใน tty1 โดยใช้Ctrl+ Alt+ F1ล็อกอินด้วยชื่อผู้ใช้และรหัสผ่านของคุณแล้วเรียกใช้คำสั่งต่อไปนี้:

sudo service lightdm restart

หมายเหตุ: ใช้Ctrl+ Alt+ F7เพื่อสลับไปที่เซสชันกราฟิก

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

  1. ใส่สคริปต์ของคุณใน /etc/rc0.d
  2. ทำให้ปฏิบัติการได้: sudo chmod +x K99_script
  3. หมายเหตุ:
    • สคริปต์ในไดเรกทอรีนี้จะทำงานตามลำดับตัวอักษร
    • ชื่อสคริปต์ของคุณจะต้องเริ่มต้นด้วยK99การเรียกใช้ในเวลาที่เหมาะสม

วิธีรันสคริปต์เมื่อปิดเครื่อง:

  1. ใส่สคริปต์ของคุณใน /etc/rc6.d
  2. ทำให้ปฏิบัติการได้: sudo chmod +x K99_script
  3. หมายเหตุ:
    • สคริปต์ในไดเรกทอรีนี้จะทำงานตามลำดับตัวอักษร
    • ชื่อสคริปต์ของคุณจะต้องเริ่มต้นด้วยK99การเรียกใช้ในเวลาที่เหมาะสม

แหล่งที่มา:


4
เป็นเรื่องธรรมดาที่จะตั้งชื่อสคริปต์เริ่มต้นด้วยK'Kill' และS'Start'
kiri

เกิดอะไรขึ้นถ้าสคริปต์ต้องการสิทธิ์ sudo เท่าที่ฉันสามารถบอกได้สคริปต์ /etc/rc6.d จะถูกเรียกใช้ในฐานะผู้ใช้และไม่สามารถใช้ gksudo ได้
Urhixidur

1
ใช้งานไม่ได้กับฉันที่ 14.04 มีการเปลี่ยนแปลงหรือไม่ระบุข้อเท็จจริงที่สำคัญหรือไม่
tomasb

2
คำแนะนำ K99 ไม่ดีสำหรับการปิด / รีบูตหากคุณต้องการบันทึกข้อมูลบางอย่างเพราะมันเกิดขึ้นหลังจากที่ unmount และ K ถูกใช้เพื่อปิดการใช้งานสคริปต์ (ดู /etc/rcS.d/README) ใช้ S เพื่อเริ่มและวางก่อน unmounts สำหรับสถานที่การบูตเครื่องสคริปต์ของคุณหลังจากติดได้ติดอยู่ในนี้เพราะข้อมูลที่ผิดนี้แก้ไขได้ด้วย S เป็นตัวอักษรตัวแรก
tomasb

6
นี่เป็นสิ่งที่ผิดมาก: i) ชื่อสคริปต์ต้องเริ่มต้นด้วยKสำหรับ runlevels 0, 1 และ 6 และSสำหรับ runlevels 2, 3, 4 และ 5; ii) คุณไม่จำเป็นต้องเรียกสคริปต์K99_fooหมายเลขจะเป็นตัวกำหนดลำดับที่สคริปต์จะทำงานคุณต้องเลือกรายการที่มีขนาดใหญ่กว่าสคริปต์อื่นหากคุณต้องการให้สคริปต์รันล่าสุด iii) Runlevel 0 ไม่ใช่การรีบูท! ; มันใช้สำหรับปิดเครื่อง 6 สำหรับรีบูต iv) สคริปต์ไม่มีธุรกิจที่อยู่ใน/etc/rcN.dไดเรกทอรี แทนพวกเขาควรจะอยู่ใน/etc/init.dและเชื่อมโยง/etc/rcN.dไปยัง
terdon

14

จะทำอย่างไรกับ systemd

หากคุณพบกระทู้นี้หลังจากเดือนมิถุนายน 2559 อูบุนตูและอนุพันธ์รวมถึงมิ้นท์จะใช้ systemd เพื่อควบคุมการเริ่มต้นและปิดระบบ ฉันมีปัญหากับวิธีการแบบเก่าดังนั้นค้นคว้าวิธี systemd

ด้วย 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 เข้าสู่เป้าหมายผู้ใช้หลายคนและบริการหยุดเมื่อออกจากเป้าหมายผู้ใช้หลายคน ไฟล์บริการทางเลือกที่มีเงื่อนไขการเปิดใช้งานที่แตกต่างกันจะอธิบายไว้ด้านล่าง


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

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

สร้างเริ่มต้นและเปลือกปิดสคริปต์ด้วยบรรทัดแรกและทำให้พวกเขาปฏิบัติการใช้#!/bin/shchmod +x my_new_filename

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

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 สำหรับการปิดเครื่อง

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

ไฟล์นี้มีการเสนอในคำตอบที่ Unix & Linux โดย @Matthias แต่ฉันไม่สามารถเรียกใช้จนกว่าฉันจะเพิ่มส่วนการติดตั้ง

อีกครั้งแก้ไขสคริปต์ในและเปิดใช้งานได้โดยใช้/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

1
แม้ว่าโพสต์ของคุณจะถูกต้องฉันขอแนะนำให้ปรับปรุงโดยเพิ่มตัวอย่างว่าขั้นตอนดังกล่าวสามารถทำได้กับระบบ โปรดแจ้งให้เราทราบเมื่อคุณแก้ไขคุณโพสต์ ขอขอบคุณและยินดีต้อนรับสู่ AskUbuntu
Sergiy Kolodyazhnyy

สวัสดี Serg คุณหมายถึงตัวอย่างเช่นในโพสต์ที่เชื่อมโยงหรือคุณมีอย่างอื่นในใจ? ประการที่สองฉันไม่แน่ใจว่าจะ "แจ้งให้คุณทราบได้อย่างไร" เพราะฉันไม่สามารถหากลไกในการติดต่อผู้ใช้ SO รายอื่นได้
จอห์น 9631

ใช่คุณสามารถให้ตัวอย่างเช่นเดียวกับในโพสต์อื่น ๆ ของคุณ เพียงแค่พูดว่า "ไปที่ลิงค์อื่น" นั้นไม่ดีมากและทำให้คำตอบของคุณดูขี้เกียจ นอกจากนี้สำหรับการติดต่อผู้ใช้ SO อื่นให้ใช้ @ ก่อนชื่อผู้ใช้ตัวอย่างเช่น @Serg
Sergiy Kolodyazhnyy

ปรับปรุงมาก ดีมากติดตามงานที่ดี!
Sergiy Kolodyazhnyy

1
ตามที่man systemd.unitผู้ใช้สร้างไฟล์สามารถวางใน$XDG_CONFIG_HOME/systemd/userและสถานที่ผู้ใช้ในท้องถิ่นอื่น ๆ
Antonios Hadjigeorgalis
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.