最近、2つの異なるLinuxホストで2つの異なる問題が発生しました。私はまだ本当の解決策を見つけていないので、それぞれに固有の回避策が必要でした。ただし、各回避策を提供する方法は同じでした。Linuxの起動中または起動直後にコマンドを実行します。
rc.local
ファイルは、Linuxシステム管理者が起動時に実行する必要のあるコマンドを配置する場所であり、場合によってはまだ存在します。 rc.local
の使用 ファイルは非推奨になるだけでなく、数時間の試行の後、いずれにしても機能しませんでした。これは、systemd
ドキュメントには、systemd
を生成する「ジェネレータ」の使用について記載されています rc.local
からのサービス 存在する場合はファイル。 (これは、非推奨を強制するための良い方法のようです。機能しないようにしてください。)
私の特定の問題の詳細はこの議論に特に関係がないので、ローカルのスタートアップファイルのコンテンツとしてシンプルで簡単に追跡できるコマンドを使用します。ローカルログファイルに日付スタンプの行を追加して、起動時に実行する必要のあるBashプログラムが実際に機能することを確認します。
Linuxの起動と起動のプロセスを理解することは、Linuxを構成し、起動の問題を解決するために重要です。実際には、Linuxコンピューターを起動して使用可能にするために必要なイベントのシーケンスは、起動と起動の2つです。起動シーケンスは、コンピューターの電源がオンになったときに開始し、カーネルが初期化されてsystemd
されたときに終了します。 が起動されます。その後、起動プロセスが引き継ぎ、Linuxコンピュータを動作状態にするタスクを終了します。
全体として、Linuxの起動と起動のプロセスは非常に簡単に理解できます。これは、以下のステップで構成されています。これについては、後で詳しく説明します。
- BIOS電源投入時自己診断(POST)
- ブートローダー(GRUB2)
- カーネル
-
systemd
起動シーケンスと起動シーケンスの両方の詳細については、私の記事「Linuxの起動プロセスと起動プロセスの概要」を参照してください。
システム管理者は、ローカルで役立つコマンドを起動シーケンスに追加することがあります。これらの追加は、標準のsystemd
の一部ではないローカルプロセスを開始または実行することを目的としている場合があります 起動。新しいsystemd
を追加することが可能です 起動時に必要な各プログラムを起動するサービスユニットですが、古いrc.local
メソッドは、すべてのローカルスタートアップのニーズに対応する単一の実行可能ファイルを提供しました。私たちも、systemd
でこの単一ファイルアプローチを使用できます 。このソリューションの優れた点は、systemd
にサービスユニットを追加しなくても、後で簡単にスタートアップコマンドを追加できることです。 。
私たちの解決策は、単一のsystemd
を作成することです サービスユニットを使用して、必要なLinuxコマンドを実行可能ファイルに配置します。このソリューションには2つの部分があります。 1つは明らかです。実行可能ファイルが必要です。 2つ目は、systemd
のサービスユニットを作成する必要があることです。 実行可能ファイルを実行します。
これは、Bashプログラミングに精通しているシステム管理者にとっては簡単な演習です。実際、Bashプログラムを作成し、ローカル実行可能ファイルのLinux Filesystem Hierarchical Standard(FHS)の場所/usr/local/bin
に配置します。 。この実行可能ファイルを別の場所に配置することについて議論することもできますが、/usr/local/bin
この場所では、必要に応じてシステム管理者がコマンドラインからスクリプトを簡単に実行できるため、これが私にとって最も理にかなっている場所です。 /usr/local/bin
ディレクトリは常にすべてのユーザーの$PATH
にあります 、rootユーザーのものを含みます。
mystartup.sh
を作成します ここに表示されているファイルを/usr/local/bin
に配置します (必ず実行可能にしてください)。配布に適したBashの場所を使用してください。たとえば、DebianベースのディストリビューションはBashを/bin/bash
に配置します 。
#!/usr/bin/bash
################################################################################
# mystartup.sh
#
# This shell program is for testing a startup like rc.local using systemd.
# By David Both
# Licensed under GPL V2
#
################################################################################
# This program should be placed in /usr/local/bin
################################################################################
# This is a test entry
echo `date +%F" "%T` "Startup worked" >> /root/mystartup.log
注: 含まれているファイルのコメントは、それらを配置する必要がある場所を示しています。
この実行可能ファイルは、コマンドラインから実行してテストしてください。このシェルスクリプトを初めて実行すると、新しいファイル/root/mystartup.log
が表示されます。 、テキストとともに日時を指定して、"Startup worked"
。このログファイルを作成し、スクリプトが機能していることを確認するための簡単なテストとして、スクリプトが実行されるたびに行を追加します。
スクリプトをさらに数回実行します。結果は次のようになります:
[root@testvm1 ~]# mystartup.sh
[root@testvm1 ~]# cat mystartup.log
2019-09-12 19:58:00 Startup worked
2019-09-12 19:58:17 Startup worked
2019-09-12 19:58:54 Startup worked
2019-09-12 19:59:00 Startup worked
2019-09-12 20:01:08 Startup worked
2019-09-12 20:04:01 Startup worked
2019-09-12 20:04:13 Startup worked
2019-09-12 20:06:11 Startup worked
2019-09-12 20:06:28 Startup worked
2019-09-16 09:51:21 Startup worked
2019-09-16 09:51:51 Startup worked
最終的にローカルの起動コマンドを含む可能性のあるファイルを作成するために必要なのはこれだけです。起動時に実行する必要があるものをこのファイルに追加するだけです。
ここで作成するサービスユニットは、標準のsystemd
です。 サービスユニットファイル。この単純なファイルは、mystartup.sh
を実行するためにのみ使用されます 起動時のスクリプト。
新しいファイル/usr/local/lib/systemd/system/mystartup.service
を作成します 、以下に示す内容を追加します:
################################################################################
# mystartup.service
#
# This service unit is for testing my systemd startup service
# By David Both
# Licensed under GPL V2
#
################################################################################
# This program should be placed in /usr/local/lib/systemd/system/.
# Create a symlink to it from the /etc/systemd/system directory.
################################################################################
[Unit]
Description=Runs /usr/local/bin/mystartup.sh
[Service]
ExecStart=/usr/local/bin/mystartup.sh
[Install]
WantedBy=multi-user.target
このファイルは実行可能である必要はありません。このファイルは、/etc/systemd/system
にもあります。 、ただし、ローカルファイルとしては、/usr/local
に配置することをお勧めします。 ディレクトリ構造のブランチ。/etc/systemd.system
からのリンクがあります。 。
次に、/etc/systemd/system
に移動します サービスユニットファイルにシンボリックリンクを作成します:
[root@testvm1 system]# ln -s /usr/local/lib/systemd/system/mystartup.service
最終テストのためにLinuxホストを再起動する前に、最終サービスユニットファイルをテストする必要があります。まず、systemd
であることを確認しましょう サービスが表示されます:
[root@testvm1 ~]# systemctl status mystartup
● mystartup.service - Runs /usr/local/bin/mystartup.sh
Loaded: loaded (/usr/local/lib/systemd/system/mystartup.service; linked; vendor preset: disabled)
Active: inactive (dead)
[root@testvm1 ~]#
この結果は、サービスがsystemd
によって認識されていることを示しています。 。それでは、サービスを開始しましょう。そうすることでスクリプトは実行されますが、起動時に実行するように新しいサービスを構成することはありません:
[root@testvm1 ~]# systemctl start mystartup
ログファイルの内容をチェックして、新しい行が追加されたことを確認します。
あとは、起動時に実行されるようにサービスを有効にするだけです。
[root@testvm1 ~]# systemctl enable mystartup
Created symlink /etc/systemd/system/multi-user.target.wants/mystartup.service →
/usr/local/lib/systemd/system/mystartup.service.
[root@testvm1 ~]#
再起動する前に、journalctl
を見てみましょう。 コマンドと、それを使用してmystartup.service
に関連するジャーナルエントリを表示する方法 。 journalctl
を使用することもできます systemd
であるため、これを確認するコマンド 実行するすべてのジャーナルを保持します。
次のコマンドでは、-u
オプションは、mystartup
のエントリのみを表示します 単位:
[root@testvm1 ~]# journalctl -u mystartup
-- Logs begin at Mon 2019-04-15 22:50:27 EDT, end at Mon 2019-09-16 11:44:30 EDT. --
Sep 16 11:09:28 testvm1 systemd[1]: Started Runs /usr/local/bin/mystartup.sh.
[root@testvm1 ~]#
次に、Linuxホストを再起動し、ログファイルをチェックして、新しい行が追加されたことを確認します。
[root@testvm1 ~]# systemctl status mystartup
● mystartup.service - Runs /usr/local/bin/mystartup.sh
Loaded: loaded (/usr/local/lib/systemd/system/mystartup.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Mon 2019-09-16 11:45:59 EDT; 1min 30s ago
Process: 819 ExecStart=/usr/local/bin/mystartup.sh (code=exited, status=0/SUCCESS)
Main PID: 819 (code=exited, status=0/SUCCESS)
Sep 16 11:45:55 testvm1 systemd[1]: Started Runs /usr/local/bin/mystartup.sh.
[root@testvm1 ~]# journalctl -u mystartup
-- Logs begin at Mon 2019-04-15 22:50:27 EDT, end at Mon 2019-09-16 11:47:45 EDT. --
Sep 16 11:09:28 testvm1 systemd[1]: Started Runs /usr/local/bin/mystartup.sh.
-- Reboot --
Sep 16 11:45:55 testvm1 systemd[1]: Started Runs /usr/local/bin/mystartup.sh.
[root@testvm1 ~]#
この実験用に作成したBashシェルスクリプトは、起動時に1回実行され、その後終了します。デーモンとしては設計されていないため、デーモンとしてメモリに残りません。
お気づきの方もいらっしゃると思いますが、ローカルスタートアップサービスの作成に使用した手順を使用して、systemd
の新しいサービスを作成することもできます。 。方法がわかれば、それほど難しくはありません。
更新
この記事が公開された直後に、トム・マーフィーからrc-local
の存在を通知するメールを受け取りました。 systemd
の一部であるサービス 。そのサービスを知らなかったので、そのメールに感謝し、何か新しいことを学びました。
古いrc.local
のサポートを追加することができます systemctl enable rc-local
コマンドでサービスを有効にしてファイルを作成します 。 rc.localファイルのコマンドは、次回の起動時に実行されます。もちろん、systemctl enable rc-local
を使用できます rc.local
を実行するには すぐに。
ただし、rc.localが廃止されたことは事実です。 systemd-rc-local-generator
のマニュアルページ 「/etc/rc.localのサポートは、特定のSystemVシステムとの互換性のためにのみ提供されています。ただし、今日このスクリプトを使用することは避け、代わりに、ブートプロセス中に実行するスクリプトに適切な依存関係を持つ適切なユニットファイルを提供することを強くお勧めします。」
-
Linux用Linuxファイルシステム階層標準(FHS)DataBook
-
GNUGRUB情報
-
GNUGRUBマニュアル
-
マスターブートレコード
-
マルチブート仕様
-
systemd情報
-
systemdの起動プロセス
-
マニュアルページのsystemdインデックス
-
Linuxの起動および起動プロセスの概要
[Red Hat Enterprise Linuxを試してみませんか?今すぐ無料でダウンロードしてください。]