Kapatmadan önce bir komut yürütün


52

Bilgisayar kapanmadan hemen önce basit bir komut çalıştırmak istiyorum (zamanlama gerekli değildir).

Başlangıç ​​için /etc/rc.local; kapatma için benzer bir şey var mı?

Hala menüden entegre kapatma düğmesini kullanmak istediğimi unutmayın; yani, her terminalde kapattığımda özel bir script kullanmak istemiyorum - otomatik olması gerekiyor.

Yanıtlar:


42

Linux Mint Ubuntu'ya dayanıyor, bu yüzden runlevel sisteminin muhtemelen aynı olduğunu sanıyorum. Ubuntu'da, farklı çalışma seviyeleri için komut dosyaları /etc/rc[0-6].ddizinlerdeki varlıklarına göre yürütülür . Runlevel 0, kapanmaya karşılık gelir ve 6 yeniden başlatmak için kullanılır.

Tipik olarak betiğin kendisi saklanır /etc/init.dve daha sonra ihtiyaç duyduğunuz çalışma seviyelerine karşılık gelen dizinlere sembolik bağlantılar yerleştirilir.

Bu durumda, komut dosyanızı yazın, saklayın /etc/init.d/, ardından her birinde bir sembolik bağlantı oluşturun /etc/rc0.dve /etc/rc6.d( her ikisini de istiyorsanız) komut dosyanızı işaret edin.

Her çalışma seviyesindeki dizindeki komut dosyaları asil-sırasına göre yürütülecektir , bu nedenle çalışma seviyesindeki sıra sizin için önemliyse , bağlantı linkinizin adını buna göre seçin.


Sadece init.d'deki (kubuntu kesin) iskelet dosyasına bir göz attım ve biraz korktum. Kapanma tarihini / var / log altındaki bir dosyaya ekleyen bir çift komut eklemek istiyorum. Bunu yapabilir miyim yoksa iskelet dosyasındaki bazı şeylerle uğraşmak zorunda mıyım?
Joe

2
@Joe - Senaryonuzun standart bir servis olarak kontrol edilebilir olmasını istemediğiniz sürece bunların çoğuna ihtiyacınız olmaz. Basit bir yankı ile hiçbir şeyi kendi log dosyasına bozmazsınız, o yüzden deneyin ve görün.
ire_and_curses

1
İşte basit bir örnek init.d betiği. Ayrıca, sembolik bağlantıları kullanmak daha kolay ve daha sağlamdırsudo update-rc.d /etc/init.d/myservice defaults
RolfBly

/Etc/init.d/spark_shutdown.sh yazdım ve /etc/rc0.d & /etc/rc6.d içinde link oluşturdum. Şimdi bu komut dosyasının ubuntu aws ec2 örneğinde çalıştığını nasıl onaylarım
Ashish Karpe

10

Şimdi Ubuntu varyantları ve Mint sisteme taşındı ve yukarıdakilere dayanarak eski çözümümün daha az tatmin edici olduğunu gördüm. Systemd ile nasıl yapılacağını bulmak için web'de arama yaptım ve başkalarının bilgeliğini bir araya getirip blogspot.com.au'da aşağıdaki öğreticiyi içeren bir blog yazısı olarak belgeledim .

Systemd ile, aşağıdaki şablonları kullanarak scriptlerinizi çağırmak için bir veya iki dosya yaratır ve birkaç komutu yerine getirirsiniz. Basit.


GUI Sürümü

Öncelikle , başlangıçta ve / veya kapanışta çalıştırmak istediğiniz komut dosyalarını oluşturun. .Scopening_atstart ve .scfullcopy_atend 'ı oluşturdum.

Sonra her ikisinin de çalıştırılabilir olduğundan emin olun, dosyayı sağ tıklayın, özellikleri seçin ve izinler altında, dosyayı bir program olarak yürütmeye izin ver seçeneğinin işaretli olduğundan emin olun.

Oluşturduğum iki dosya bir ramdisk içeriğini dolduruyor ve kaydediyor. Ayrıca, servisin çalıştığını kanıtlamak için giriş dizinimde bir dosya oluşturuyorlar. Şeklindeydiler:

#!/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

Daha sonra dosya yöneticimi root olarak açtım, açtım /etc/systemd/systemve bir dosya açıldı startup.service ve bir dosya save-ramdisk.service. Açıkçası kendi adınızı seçebilirsiniz ve genel adlar johns_start.service adlı bir başlangıç ​​dosyası ve johns_shutdown.service adlı bir kapatma dosyası içerebilir. Sadece mevcut servis adlarını seçmeyin.

[Unit]
Description=Startup Applications

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

[Install]
WantedBy=multi-user.target

ve

[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

Çalıştırılabilir betiğinizin tam yolunu benim için değiştirerek aynı hizmet dosyalarını kullanabilirsiniz.

Son olarak , her biri systemctl komutunu çalıştırınız, your_files_name (ancak sonek servisi olmadan). Yani benim birincisiydisystemctl enable startup

Hizmetleri başlatmak için bilgisayarı bir kez yeniden başlatın. Start hizmeti, sistem kullanıcı çok kullanıcılı hedefine her girdiğinde ve çok kullanıcılı hedefinden çıktığında stop servisine yürütülür. Farklı aktivasyon koşullarına sahip alternatif servis dosyaları aşağıda açıklanacaktır.


CLI (Komut Satırı) Sürümü

Bu açıklama / home / john yerine home dizininizden çalıştığınızı, gerektiğinde sudo kullandığını ve vim veya svim yazdığım bir editör seçimini yaptığınızı varsayar.

İlk satırda başlatma ve kapatma kabuğu komut dosyaları oluşturun ve #!/bin/shbunları çalıştırılabilir hale getirin chmod +x my_new_filename.

Yukarıdaki gibi iki dosya oluşturun veya bu örnekte, başlatma ve kapatma görevlerini işlemek için bir dosya oluşturun. Komut dizilerini ev dizinimde çalıştıracağım ama @ don_crissti Stack Exchange'de bazı alternatifler gösteriyor .

vim /etc/systemd/system/start_and_stop.service

ve dosya içeriğine kopyalayın:

[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

Ardından Hizmeti şu komutla etkinleştirin :

systemctl enable start_and_stop

ve servislerin aktif olacağı sisteminizi yeniden başlatınız. Komutlar systemctl is-enabled start_and_stopve systemctl is-active start_and_stopyeni hizmetlerinizin izlenmesinde kullanılabilir.


Kapatma için Tetikleme Koşullarını Değiştirme

Her şeyden önce dosyalar, komut dosyalarını çalıştırmaya başlamak için çok kullanıcılı ortamın açılmasını veya kapatılmasını kullanır. Aşağıdaki dosya, komut dosyalarını başlatmak için dört olası kapatma işleminin başlangıcını kullanır. Önce satırına + WantedBy satırına hedefler ekleme veya kaldırma, daha ince ayrımlar yapmanıza olanak sağlar:

Bu dosya ikinci cevap önerilmiştir bu yazının ama bir yükleme bölümü eklendi kadar çalıştırmak için alamadı.

Yine komut dosyasını düzenleyin /etc/systemd/service/ve kullanarak etkinleştirin systemctl enable your_file_name. Hedefleri değiştirdiğimde systemclt disable file_namekomutu kullandım ve sonra onu hedef dizinlere bağlayan yeniden etkinleştirdim. Yeniden başlattığınızda servis çalışacaktır.

[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

rc.shutdownLinux Çekirdeği için kapatma komut dosyasını kullanmanız gerekir . OpenBSD man sayfasından alıntı :

Sistem, yeniden başlatma (8) veya durdurma (8) komutlarını kullanarak kapatıldığında ya da init (8), bununla işaret edildiğinde veya klavyede istenen bir durdurma yapıldığında (mimari destekliyorsa), rc ( 8) `` kapatma '' argümanı ile çağrıldı.

Böylece, rc.shutdown dosyanızı açın ve yürütmek istediğiniz kabuk komutlarını ekleyin.

GÜNCELLEME: Linux Mint, farklı bir başlatma / kapatma prosedürüne sahip olan Ubuntu'ya dayandığından, sizinle ilgili prosedür:

Çalıştırmak istediğiniz kabuk betiğini yazın ve içindeki ilgili dizine kopyalayın /etc/rc*.d/. *Runlevel'a karşılık gelir; bunun ardından komut yürütmek istiyorum.
Ubuntu Debian çalışma seviyesi numaralandırmasını takip eder, bu nedenle durma için çalışma seviyesi 0 ve yeniden başlatma için çalışma seviyesi 6'ya sahipsiniz.


1

Debian Wheezy, Devuan ve türevlerinde ve belki de başkalarında kullanılan SysV bağımlılığı temelli init sistemleri için, rc.shutdownanalogun davranışını rc.localaşağıdakilere benzer şekilde taklit edebilirsiniz :

Komutlarını aşağıdaki iskelete ekle /etc/rc.shutdown:

#!/bin/sh -e
#
# rc.shutdown
#

# <add your commands here, before exit 0>

exit 0

Komut dosyasını kaydedin ve dosyayı çalıştırılabilir hale getirin chmod a+x /etc/rc.shutdown.

Ardından, /etc/init.d/rc.shutdownaşağıdaki içeriğe sahip sisteminize yeni bir komut dosyası ekleyin :

#! /bin/sh
### BEGIN INIT INFO
# Provides:          rc.shutdown
# Required-Start:
# Required-Stop:
# X-Stop-After:      umountroot
# Default-Start:
# Default-Stop:      0 6
# Short-Description: Run /etc/rc.shutdown if it exist
### END INIT INFO


PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/init/vars.sh
. /lib/lsb/init-functions

do_stop() {
    if [ -x /etc/rc.shutdown ]; then
            [ "$VERBOSE" != no ] && log_begin_msg "Running local shutdown scripts (/etc/rc.shutdown)"
        /etc/rc.shutdown
        ES=$?
        [ "$VERBOSE" != no ] && log_end_msg $ES
        return $ES
    fi
}

case "$1" in
    start)
        # No-op
        ;;
    restart|reload|force-reload)
        echo "Error: argument '$1' not supported" >&2
        exit 3
        ;;
    stop|status)
    do_stop
        exit 0
        ;;
    *)
        echo "Usage: $0 start|stop" >&2
        exit 3
        ;;
esac

Ayrıca bu betiği çalıştırılabilir yap.

/Etc/rcLEX06LEX.d içinde sembolik bağlantılar oluşturun:

cd /etc/rc0.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

ve

cd /etc/rc6.d ; ln -s ../init.d/rc.shutdown K01rc.shutdown

insservSembolleri düzeltmek ve gerekli .depend.boot, .depend.start ve .depend.stop dosyalarını oluşturmak için kullanın :

insserv -v

Yukarıda belirtilen tüm komutlar için root olmanız veya sudo kullanmanız gerekir.


Bugün bununla biraz zaman geçirdim ve Ubuntu 16 ile çalışmasını sağlayamadım, belki de bendim ama yukarıdaki çözüm hemen işe yaradı.
Mike Q
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.