脆弱性などに対応するため、Linuxサーバのパッケージを最新に保つことは重要です。
ですが、どこかでトラブルが発生した際に「どのパッケージを更新してから異常が発生したか」の履歴を追うことも必要。
そこで、以下のシェルスクリプトをChatGPTに尋ねながら作ってみました。
動作確認環境
- Ubuntu 20.04で動作を確認しました。
- 筆者の好みの関係上、パッケージ管理はaptitudeを用いています。
- また、サービス再起動の有無を確認するため、checkrestartをインストールします。(debian-goodiesをインストール)
要件
ChatGPTに要求した要件は以下の通りです。
- パッケージ一覧のリストを作成する。
- パッケージ全体のupdateを行う。
- そのupdateで差異があった場合はファイルに出力して更新を行う。
- サービス再起動があったらそれを標準出力とファイルに出力する。
かなりの試行を重ねて以下のスクリプトができあがりました。
スクリプト内容
- update-packages.sh
#!/bin/bash
# インストールされているパッケージの一覧を取得して別ファイルに出力します。
now=$(date +%Y%m%d)
dpkg-query -W > installed_packages_$now.txt
# aptitude updateを行います。
aptitude update
# updateの結果:
if aptitude search '~U' | grep -q '^i'; then
# 対象パッケージ,変更前バージョン,変更後のバージョン を記入した日付付きのファイルを作成。
now=$(date +%Y%m%d)
upgraded_packages=$(mktemp)
# パッケージのキャッシュをクリアした上でパッケージアップグレードを実施。
aptitude clean
aptitude -y full-upgrade | tee $upgraded_packages >/dev/null
# パッケージ一覧からの差分を別ファイルで作成。(実行日の日付を付与)
new_packages=$(mktemp)
dpkg-query -W > $new_packages
diff -u installed_packages_$now.txt $new_packages > package_diff_$now.txt
# checkrestartを実行して結果を取得
now=$(date +%Y%m%d)
checkrestart_output=$(checkrestart)
# サービスを再起動する必要のあるプロセスを抽出してファイルに出力
restart_services=$(echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | awk '{print $NF}' | sort -u)
if [[ -n "$restart_services" ]]; then
# ファイル名に日付を追加
now=$(date +%Y%m%d)
filename="restart_services_$now.txt"
echo "以下のサービスを再起動してください:" >> "$filename"
echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | grep -v "restart$" >> "$filename"
echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | grep "restart$" >> "$filename"
echo "以下のサービスを再起動してください:"
echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | grep -v "restart$"
echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | grep "restart$"
else
echo "再起動するサービスはありません"
fi
fi
記入後、以下を実施します。
sudo chown root:root update-packages.sh
# root権限で実施するため
sudo chmod 744 update-packages.sh
確認結果
sudo bash update-packages.sh
を実行後、
- 現在インストールされているパッケージのバージョンを別ファイルに出力
- パッケージのアップデート
- その際に差分があればアップグレード
- サービス再起動の有無を判断し、あればそのサービスを表示
という結果が出ました。
今後の展望
- 可読性を高くする
- 自動実行を行う
- ログ化してローテーションを行う
等は実施したいです。
コメントを残す