はじめに
この実験(Lab)では、RHEL システム管理のための Bash スクリプトの作成と実行について学びます。まず、シンプルなスクリプトを作成し、システムコマンドを追加して実行可能にします。次に、システム情報の収集などのタスクを自動化するためにforループを使用し、grepと正規表現を使用してコマンド出力をフィルタリングする方法を学びます。最終的には、包括的な RHEL システム情報スクリプトを構築し、管理タスクの自動化と強力なシェル機能の活用に関する実践的なスキルを習得します。
シンプルな Bash スクリプトの作成と実行
このステップでは、基本的な Bash スクリプトを作成し、実行する方法を学びます。Bash スクリプトは、Bash シェルが実行できる一連のコマンドを含むプレーンテキストファイルです。これらは、繰り返し行うタスクを自動化し、複数のコマンドを単一の実行可能なユニットにまとめるための強力なツールです。
まず、スクリプトを保存するための新しいディレクトリを作成します。ファイルを整理することは良い習慣であり、スクリプトを専用のディレクトリに配置すると、ホームディレクトリを整理整頓できます。
スクリプト用のディレクトリを作成します。
mkdirコマンドを使用して、~/projectディレクトリ内にscriptsという名前のディレクトリを作成します。ここに Bash スクリプトを保存します。mkdir ~/project/scriptsこのコマンドが成功した場合、直接的な出力はありません。
最初の Bash スクリプトファイルを作成します。 新しく作成した
scriptsディレクトリに移動し、nanoテキストエディタを使用してfirstscript.shという名前のファイルを作成します。.sh拡張子は、シェルスクリプトの一般的な慣例ですが、厳密には必須ではありません。cd ~/project/scripts nano firstscript.shnanoエディタ内には、空白の画面が表示されます。スクリプトに内容を追加します。 すべての Bash スクリプトは、"shebang"行、
#!/usr/bin/bashで始める必要があります。この行は、オペレーティングシステムに、スクリプトを実行するためにどのインタープリターを使用するかを指示します(この場合は Bash)。shebang の後には、ターミナルにメッセージを出力するシンプルなechoコマンドを追加します。nanoエディタに次の行を入力します。#!/usr/bin/bash echo "Hello, LabEx! This is my first Bash script."内容を入力したら、
Ctrl+O、次にファイル名を確認するためにEnter、そしてCtrl+Xを押してnanoを終了してファイルを保存します。ターミナルはコマンドプロンプトに戻ります。
bashインタープリターを使用してスクリプトを実行します。bashインタープリターに明示的に実行するように指示することで、Bash スクリプトを実行できます。この方法では、スクリプトに実行権限は必要ありません。bash firstscript.shスクリプトの出力が表示されます。
Hello, LabEx! This is my first Bash script.これにより、スクリプトが正しく作成され、正常に実行されたことが確認できます。
システムコマンドを追加し、実行可能にする Bash スクリプトの強化
このステップでは、Bash スクリプトにさらに多くのシステムコマンドを追加し、スクリプトを直接実行可能にする方法を学びます。スクリプトを実行可能にすると、bashインタープリターを明示的に呼び出すことなく、他のコマンドのように実行できます。
スクリプトディレクトリに移動します。 前のステップで
firstscript.shを作成した~/project/scriptsディレクトリにいることを確認してください。cd ~/project/scriptsfirstscript.shを編集して、より多くのシステムコマンドを含めます。 ブロックデバイスやファイルシステムの空き容量など、システム情報を表示するコマンドをスクリプトに追加します。これにより、スクリプトがシステムデータの収集を自動化する方法が示されます。nanoを使用してfirstscript.shを開きます。nano firstscript.sh次の内容に合わせてファイルの内容を変更します。このスクリプトは次のことを行います。
- ブロックデバイス情報のヘッダーを出力します。
lsblkを実行して、ブロックデバイスを一覧表示します。- ファイルシステムの空き容量のヘッダーを出力します。
df -hを実行して、ディスク容量の使用状況を人間が読める形式で表示します。
#!/usr/bin/bash echo "Hello, LabEx! This is my first Bash script." echo "#####################################################" echo "LIST BLOCK DEVICES" echo "#####################################################" lsblk echo "#####################################################" echo "FILESYSTEM FREE SPACE STATUS" echo "#####################################################" df -hCtrl+O、次にEnter、そしてCtrl+Xを押してnanoを終了してファイルを保存します。スクリプトを実行可能にします。 スクリプトを直接実行する(例:
./firstscript.sh)には、実行権限を付与する必要があります。chmodコマンドは、ファイル権限を変更するために使用されます。+xは、すべてのユーザーに実行権限を追加します。chmod +x firstscript.shこのコマンドが成功した場合、直接的な出力はありません。
スクリプトを直接実行します。 スクリプトが実行可能になったので、そのパスを指定して実行できます。現在のディレクトリにあるため、
./の後にスクリプト名を続けます。./firstscript.sh最初のメッセージと
lsblkおよびdf -hの出力を組み合わせた、次のような出力が表示されます。Hello, LabEx! This is my first Bash script. ##################################################### LIST BLOCK DEVICES ##################################################### NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 10.2G 1 loop / loop1 7:1 0 200M 1 loop /usr/local/bin loop2 7:2 0 200M 1 loop /usr/local/go loop3 7:3 0 200M 1 loop /usr/local/java loop4 7:4 0 200M 1 loop /usr/local/node loop5 7:5 0 200M 1 loop /usr/local/python ##################################################### FILESYSTEM FREE SPACE STATUS ##################################################### Filesystem Size Used Avail Use% Mounted on overlay 10G 4.0G 6.1G 40% / tmpfs 64M 0 64M 0% /dev tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup shm 64M 0 64M 0% /dev/shm /dev/loop0 10G 4.0G 6.1G 40% / tmpfs 7.8G 0 7.8G 0% /proc/asound tmpfs 7.8G 0 7.8G 0% /proc/acpi tmpfs 7.8G 0 7.8G 0% /proc/scsi tmpfs 7.8G 0 7.8G 0% /sys/firmwarelsblkとdf -hの正確な出力は、特定の環境によって若干異なる場合がありますが、コマンドの構造と出力の存在は同様であるはずです。
RHEL サーバーで For ループを使用してホスト名を取得する自動化
このステップでは、Bash のforループについて学び、複数のサーバーでタスクを自動化する方法を学びます。forループは、リスト内の各項目に対してコードブロックを繰り返し実行できる基本的な制御フロー文です。これは、複数のシステムを効率的に管理するのに特に役立ちます。
この演習では、複数のサーバーでの作業をシミュレートするために、さまざまなアプローチを使用して localhost でこの概念を説明します。
ローカルコマンドを使用してホスト名を取得します。 ループを使用する前に、ローカルシステムから通常どのようにホスト名を取得するかを見てみましょう。この概念を説明するために、さまざまな方法を使用します。
hostname hostname -f次のような出力が表示されます。
684791f71c0e35fea6cc1243 684791f71c0e35fea6cc1243これは、さまざまなオプションを使用してホスト名情報を正常に取得できることを示しています。このコンテナ環境では、すべてのホスト名オプションが同じコンテナ ID を返すことに注意してください。
さまざまなオプションを使用してホスト名取得を自動化する
forループを作成します。 次に、forループを使用して、さまざまなホスト名コマンドをより効率的に実行します。forループは、ホスト名オプションのリストを反復処理し、各オプションでhostnameコマンドを実行します。for OPTION in "" "-f" "-s"; do echo "hostname ${OPTION}:" hostname ${OPTION} echo "" doneこのコマンドを分解してみましょう。
for OPTION in "" "-f" "-s";: この部分はループを初期化します。OPTIONは、各反復処理中にリスト内の各項目(空の文字列、-f、-s)の値を受け取る変数です。do: ループで実行するコマンドの開始を示します。echo "hostname ${OPTION}:";: これは、どのオプションが使用されているかを表示します。hostname ${OPTION};: これは、各反復処理で実行されるコマンドです。${OPTION}は、OPTION変数の現在の値に展開されます。echo "";: 可読性を高めるために空白行を追加します。done: ループの終了を示します。
次のような出力が表示されます。
hostname : 684791f71c0e35fea6cc1243 hostname -f: 684791f71c0e35fea6cc1243 hostname -s: 684791f71c0e35fea6cc1243これは、さまざまなパラメーターを使用して繰り返しタスクを自動化する
forループの力を示しています。
RHEL サーバー向け For ループを使用した Bash スクリプトの作成と実行
このステップでは、前のステップで学習したforループを Bash スクリプトにカプセル化します。これにより、自動化ロジックを保存し、簡単に再利用できます。また、PATH環境変数と、任意のディレクトリからスクリプトにアクセスできるようにする方法についても学びます。
スクリプトディレクトリに移動します。
~/project/scriptsディレクトリにいることを確認してください。cd ~/project/scriptsホスト名取得用の新しいスクリプトを作成します。 さまざまなオプションを使用してホスト名情報を取得する
forループを含む、get_hostnames.shという名前のスクリプトを作成します。nanoを使用してget_hostnames.shを開きます。nano get_hostnames.sh次の内容をファイルに追加します。
#!/usr/bin/bash ## This script retrieves hostname information using different options. for OPTION in "" "-f" "-s"; do echo "Getting hostname with option: ${OPTION}" hostname ${OPTION} echo "------------------------" done exit 0Ctrl+O、次にEnter、そしてCtrl+Xを押してnanoを終了してファイルを保存します。新しい要素を分解してみましょう。
## This script...:#で始まる行はコメントです。これらはシェルによって無視されますが、スクリプトをドキュメント化するのに役立ちます。echo "Getting hostname with option: ${OPTION}": この行は、スクリプトの実行中にフィードバックを提供し、現在使用されているオプションを示します。exit 0: このコマンドは、慣例的に成功を示すステータスコード0でスクリプトを明示的に終了します。
スクリプトを実行可能にします。 前のステップと同様に、新しいスクリプトに実行権限を付与する必要があります。
chmod +x get_hostnames.shこのコマンドが成功した場合、直接的な出力はありません。
現在のディレクトリからスクリプトを実行します。 スクリプトを実行して、その機能を検証します。
./get_hostnames.sh次のような出力が表示されます。
Getting hostname with option: 684791f71c0e35fea6cc1243 ------------------------ Getting hostname with option: -f 684791f71c0e35fea6cc1243 ------------------------ Getting hostname with option: -s 684791f71c0e35fea6cc1243 ------------------------PATH環境変数を理解します。PATH環境変数は、シェルが実行可能コマンドを検索するディレクトリのリストです。lsやgrepのようなコマンドを入力すると、シェルはPATHにリストされているディレクトリを検索して、対応する実行可能ファイルを見つけます。現在の
PATH変数を表示します。echo $PATHコロンで区切られたディレクトリのリストが表示されます。例:
/home/labex/.local/bin:/home/labex/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin~/project/scripts(または/home/labex/project/scripts)は、通常、デフォルトのPATHに含まれていないことに注意してください。これが、スクリプトを実行するために./get_hostnames.shを使用する必要があった理由です。スクリプトディレクトリを
PATHに追加します(オプション、今後の参考のために)。 このラボステップでは必須ではありませんが、カスタムスクリプトを任意の場所から実行できるように、個人のbinまたはscriptsディレクトリをPATHに追加するのが一般的な方法です。export PATH=$PATH:~/project/scriptsのような行を~/.bashrcまたは~/.zshrcファイルに追加することで、これを行うことができます。このラボでは、スクリプトのパスを指定してスクリプトを実行し続けます。
RHEL で Grep と正規表現を使用してコマンド出力をフィルタリング
このステップでは、grepコマンドと正規表現を使用して、コマンド出力とファイルから特定の情報を効率的にフィルタリングして抽出する方法を学びます。grepは、プレーンテキストデータセットから正規表現に一致する行を検索するための強力なユーティリティです。正規表現(regex)は、検索パターンを定義する文字のシーケンスです。
システムファイルで特定のユーザーとグループ情報を検索します。
/etc/passwdファイルと/etc/groupファイルからlabexユーザーとグループに関する情報を検索するために、grepを使用します。これらのファイルは、それぞれユーザーとグループのアカウント情報を格納します。まず、
/etc/passwdでlabexユーザーエントリを検索してみましょう。grep "labex" /etc/passwd期待される出力:
labex:x:1000:1000::/home/labex:/bin/bash次に、
/etc/groupでlabexグループエントリを検索します。grep "labex" /etc/group期待される出力:
labex:x:1000:これらのコマンドは、正確な文字列の一致を見つけるための基本的な
grepの使用法を示しています。grepと正規表現を使用してlscpu出力をフィルタリングします。lscpuコマンドは、CPU アーキテクチャ情報を表示します。多くの場合、その広範な出力から特定の行のみが必要になります。正規表現とともにgrepを使用して、「CPU」で始まる行をフィルタリングできます。lscpu | grep '^CPU'このコマンドを分解してみましょう。
lscpu: CPU 情報を生成します。|: これはパイプであり、lscpuの標準出力を取得し、それをgrepコマンドへの標準入力としてフィードします。grep '^CPU': リテラル文字列「CPU」で始まる行を検索します。^(キャレット)は、行の先頭に一致する正規表現アンカーです。
期待される出力(環境によって若干異なる場合があります):
CPU op-mode(s): 32-bit, 64-bit CPU(s): 4 CPU family: 6コメントと空行を無視して、設定ファイルをフィルタリングします。 設定ファイルには、実際の構成とは関係のないコメント(
#で始まる行)と空行が含まれていることがよくあります。複数のパターンを持つgrepを使用して、これらの行を除外できます。/etc/passwdファイルでこれを示してみましょう。grep -v '^#' /etc/passwd | head -5このコマンドを分解してみましょう。
grep -v '^#' /etc/passwd:-vオプションは一致を反転させます。つまり、パターンに一致しない行を選択します。^#は、#で始まる行に一致します。したがって、この部分はコメント行をフィルタリングします。|: 最初のgrepコマンドの出力を次のコマンドにパイプします。head -5: 出力の最初の 5 行のみを表示します。
期待される出力(コメントなしのユーザーアカウントエントリを表示):
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologinシステムファイルで特定のパターンを検索します。
grepを使用して、さまざまなシステムファイルで特定のパターンを検索できます。/etc/passwdファイルでシェル関連のエントリを検索してみましょう。grep "bash" /etc/passwd期待される出力(bash シェルを持つユーザーを表示):
root:x:0:0:root:/root:/bin/bash labex:x:1000:1000::/home/labex:/bin/bashこのコマンドは、bash をデフォルトシェルとして持つユーザーを識別するのに役立ちます。
RHEL システム情報スクリプトの包括的な構築
この最終ステップでは、これまでに学習したすべての概念(Bash スクリプティング、forループ、リモート実行のためのssh、フィルタリングのための正規表現を使用したgrep)を組み合わせて、複数の RHEL サーバーからシステム情報を収集する包括的なスクリプトを構築します。スクリプトは、収集したデータをサーバーごとに個別の出力ファイルに保存します。
スクリプトディレクトリに移動します。
~/project/scriptsディレクトリにいることを確認してください。cd ~/project/scriptssystem_info.shという名前の新しいスクリプトを作成します。 このスクリプトは、さまざまなアプローチを使用してシステム情報を収集し、その出力を~/projectディレクトリ内の個別のファイルにリダイレクトします。nanoを使用してsystem_info.shを開きます。nano system_info.sh次の内容をファイルに追加します。
#!/usr/bin/bash ## Define variables for output directory OUT_DIR='/home/labex/project' ## Loop through different information gathering approaches for APPROACH in "basic" "detailed"; do OUTPUT_FILE="${OUT_DIR}/output-${APPROACH}.txt" echo "Gathering ${APPROACH} system information..." ## Clear previous output file or create a new one > "${OUTPUT_FILE}" ## Get hostname information echo "#### Hostname Information ###" >> "${OUTPUT_FILE}" if [ "${APPROACH}" = "basic" ]; then hostname >> "${OUTPUT_FILE}" else hostname -f >> "${OUTPUT_FILE}" fi echo "" >> "${OUTPUT_FILE}" ## Add a blank line for readability ## Get CPU information (only lines starting with CPU) echo "#### CPU Information ###" >> "${OUTPUT_FILE}" lscpu | grep '^CPU' >> "${OUTPUT_FILE}" echo "" >> "${OUTPUT_FILE}" ## Get system users with bash shell echo "#### Users with Bash Shell ###" >> "${OUTPUT_FILE}" grep "bash" /etc/passwd >> "${OUTPUT_FILE}" echo "" >> "${OUTPUT_FILE}" ## Get system information based on approach if [ "${APPROACH}" = "basic" ]; then echo "#### Basic System Info ###" >> "${OUTPUT_FILE}" uname -r >> "${OUTPUT_FILE}" else echo "#### Detailed System Info ###" >> "${OUTPUT_FILE}" uname -a >> "${OUTPUT_FILE}" fi echo "" >> "${OUTPUT_FILE}" echo "Information saved to ${OUTPUT_FILE}" echo "-----------------------------------------------------" done echo "Script execution complete."Ctrl+O、次にEnter、そしてCtrl+Xを押してnanoを終了してファイルを保存します。このスクリプトの主な要素:
OUT_DIR='/home/labex/project': スクリプトをより柔軟で読みやすくするために使用される変数です。OUTPUT_FILE="${OUT_DIR}/output-${APPROACH}.txt": 各アプローチに対して出力ファイル名を動的に構築します。> "${OUTPUT_FILE}": 空のコマンドの出力をファイルにリダイレクトし、存在する場合はその内容を効果的にクリアし、存在しない場合は作成します。これにより、各実行で新しいファイルが確保されます。>> "${OUTPUT_FILE}": コマンドの出力を指定されたファイルに追加します。if [ "${APPROACH}" = "basic" ]; then ... else ... fi: 使用されているアプローチに基づいて異なるコマンドを実行する条件文です。echo "#### Section Header ###": より良い整理のために、出力ファイルに明確なヘッダーを追加します。
スクリプトを実行可能にします。
chmod +x system_info.shこのコマンドが成功した場合、直接的な出力はありません。
system_info.shスクリプトを実行します。 包括的なスクリプトを実行します。さまざまなアプローチを使用してシステム情報を収集し、結果を個別のファイルに保存します。./system_info.shスクリプトの進行状況を示す出力がターミナルに表示されます。
Gathering basic system information... Information saved to /home/labex/project/output-basic.txt ----------------------------------------------------- Gathering detailed system information... Information saved to /home/labex/project/output-detailed.txt ----------------------------------------------------- Script execution complete.生成された出力ファイルを確認します。
~/projectディレクトリにあるoutput-basic.txtおよびoutput-detailed.txtファイルの内容を確認して、スクリプトが期待どおりに情報を収集したことを確認します。cat ~/project/output-basic.txt cat ~/project/output-detailed.txt各ファイルの内容は、次のようになります(実際の値は異なります)。
output-basic.txt:
#### Hostname Information ### 684791f71c0e35fea6cc1243 #### CPU Information ### CPU op-mode(s): 32-bit, 64-bit CPU(s): 4 CPU family: 6 #### Users with Bash Shell ### root:x:0:0:root:/root:/bin/bash labex:x:1000:1000::/home/labex:/bin/bash #### Basic System Info ### 5.4.0-162-genericoutput-detailed.txt:
#### Hostname Information ### 684791f71c0e35fea6cc1243 #### CPU Information ### CPU op-mode(s): 32-bit, 64-bit CPU(s): 4 CPU family: 6 #### Users with Bash Shell ### root:x:0:0:root:/root:/bin/bash labex:x:1000:1000::/home/labex:/bin/bash #### Detailed System Info ### Linux 684791f71c0e35fea6cc1243 5.4.0-162-generic #179-Ubuntu SMP Mon Aug 14 08:51:31 UTC 2023 x86_64 x86_64 x86_64 GNU/Linuxこの最終的なスクリプトは、さまざまな Bash 機能と Linux コマンドを組み合わせて、システム管理タスク用の強力な自動化ツールを作成する方法を示しています。
まとめ
この実験では、RHEL システム管理のための Bash スクリプトの作成と実行に関する基本的な手順を学びました。まず、スクリプト専用のディレクトリを設定し、shebang 行の重要性とechoコマンドの使用を理解しながら、シンプルな Bash スクリプトを作成しました。bashインタープリターで直接実行する方法や、実行可能にすることなど、スクリプトを実行するさまざまな方法を検討しました。
さらに、さまざまなアプローチでシステム情報を収集するために、forループを使用してシステムコマンドを組み込み、タスクを自動化することにより、スクリプト作成スキルを向上させました。また、システム情報を解析するための重要なスキルである、grepと正規表現を使用してコマンド出力を効果的にフィルタリングする方法も学びました。最後に、これらの概念を適用して、包括的な RHEL システム情報スクリプトを構築し、さまざまなコマンドとスクリプト構造を組み合わせて、貴重なシステムデータを収集して提示する方法を示しました。



