web-dev-qa-db-ja.com

シャットダウン前にコマンドを実行する

コンピューターがシャットダウンする直前に簡単なコマンドを実行したい(タイミングは必須ではありません)。

起動には/etc/rc.localを使用できます。シャットダウンに似たものはありますか?

メニューから統合シャットダウンボタンを引き続き使用したいことに注意してください。つまり、ターミナルからシャットダウンするたびにカスタムスクリプトを使用したくありません-自動である必要があります。

55
Primož Kralj

Linux MintはUbuntuに基づいているため、ランレベルシステムもおそらく同じだと思います。 Ubuntuでは、さまざまなランレベルのスクリプトが/etc/rc[0-6].dディレクトリにあるかどうかに応じて実行されます。 Runlevel 0はシャットダウンに対応し、6はリブートに対応します。

通常、スクリプト自体は/etc/init.dに格納され、シンボリックリンクは必要なランレベルに対応するディレクトリに配置されます。

したがって、あなたのケースでは、スクリプトを記述して/etc/init.d/に保存し、スクリプトを指す/etc/rc0.d/etc/rc6.dの両方にシンボリックリンクを作成します(両方が必要な場合)。

各ランレベルディレクトリのスクリプトは asciibetical order で実行されるため、ランレベル内の順序が重要な場合は、それに応じてシンボリックリンクの名前を選択してください。

44
ire_and_curses

UbuntuのバリアントとMintがsystemdに移動したので、上記に基づく古いソリューションは満足度が低いことがわかりました。私はsystemdでそれを行う方法を見つけるためにWebを検索し、他の人の知恵を組み合わせ、それを blogspot.com.a のブログ投稿として次のチュートリアルを含むように文書化しました。

Systemdでは、以下のテンプレートを使用してスクリプトを呼び出す1つまたは2つのファイルを作成し、いくつかのコマンドを実行します。シンプル。


GUIバージョン

最初に起動時またはシャットダウン時に実行するスクリプトを作成します。 .scopening_atstartと.scfullcopy_atendを作成しました。

次に、ファイルを右クリックし、プロパティを選択して、アクセス許可の下で、[ファイルの実行を許可するプログラム。

私が作成した2つのファイルは、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

次にファイルマネージャーをrootとして開き、/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 enable your_files_nameコマンドを実行します(ただし、サフィックスサービスはありません)。だから私の最初のものはsystemctl enable startupでした

コンピュータを1回再起動して、サービスを開始します。開始サービスはsystemdがマルチユーザーターゲットに入るたびに実行され、停止サービスがマルチユーザーターゲットから出るときに実行されます。異なるアクティベーション条件を持つ代替サービスファイルについては、以下で説明します。


CLI(コマンドライン)バージョン

この説明は、/ home/johnではなくホームディレクトリから操作し、必要に応じてSudoを使用し、vimまたはsvimを記述するエディターを選択することを前提としています。

Create最初と#!/bin/shのシェルスクリプトを起動およびシャットダウンし、chmod +x my_new_filenameを使用して実行可能にします。

Create上記の2つのファイル、またはこの例では、起動タスクとシャットダウンタスクを処理する1つのファイル。ホームディレクトリでスクリプトを実行しますが、@ don_crisstiは Stack Exchange でいくつかの代替案を示します。

vim /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は、新しいサービスの監視に使用できます。


シャットダウンのトリガー条件の変更

上記のファイルはすべて、マルチユーザー環境のオープンまたはクローズを使用して、スクリプトの実行を開始します。以下のファイルは、4つの潜在的なシャットダウンプロセスの開始を使用して、スクリプトを開始します。 Before行+ WantedBy行でターゲットを追加または削除すると、より細かく区別できます。

このファイルは2番目の回答 (この投稿の) で提案されましたが、インストールセクションを追加するまで実行できませんでした。

もう一度、/etc/systemd/service/のスクリプトを編集し、systemctl enable your_file_nameを使用して有効にします。ターゲットを変更したときは、systemclt disable file_nameコマンドを使用して、ターゲットディレクトリにシンボリックリンクしたコマンドを再度有効にしました。再起動するとサービスが作動します。

[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
12
John 9631

Linuxカーネルのシャットダウンスクリプトrc.shutdownを使用する必要があります。 OpenBSD man page を引用すると:

システムがreboot(8)またはhalt(8)コマンドを使用してシャットダウンされたとき、またはinit(8)がそのように通知されたとき、またはキーボード要求の停止が発行されたとき(アーキテクチャーがサポートしている場合)、rc( 8)引数「shutdown」で呼び出されます。

したがって、rc.shutdownを開いて、実行するシェルコマンドを追加するだけです。

更新:Linux Mintは、起動/シャットダウンの手順が異なるUbuntuに基づいているため、次の手順が該当します。

実行するシェルスクリプトを記述し、/etc/rc*.d/の関連ディレクトリにコピーします。 *は、スクリプトを実行するランレベルに対応しています。
UbuntuはDebianランレベルの番号付けに従うため、停止にはランレベル0、再起動にはランレベル6があります。

7
darnir

Debian Wheezy、Devuanおよびその派生物で使用されているSysV依存ベースのinitシステムでは、rc.shutdownアナログとrc.localの動作を次のように模倣できます。

次の/etc/rc.shutdownのスケルトンにコマンドを追加します。

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

# <add your commands here, before exit 0>

exit 0

スクリプトを保存し、chmod a+x /etc/rc.shutdownを使用してファイルを実行可能にします。

次に、次の内容で新しいスクリプト/etc/init.d/rc.shutdownをシステムに追加します。

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

また、このスクリプトを実行可能にします。

/etc/rc[06].dにシンボリックリンクを作成します。

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

そして

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

insservを使用してシンボリックリンクを修正し、必要な.depend.boot、.depend.start、および.depend.stopファイルを作成します。

insserv -v

上記のすべてのコマンドで、rootになるか、Sudoを使用する必要があります。

1
Adrian Zaugg