この記事の更に続きとなります。

以前作成したスクリプトに問題点があったので修正します。

問題点詳細

アップデートするパッケージによってはコンフィグを残すか否かをアップデート中に聞いてきます。

このプロンプトが表示されるとスクリプトは停止。処理を手動で中断して実行する羽目になります。

これを回避するため、以下のように修正いたしました。

修正差分

-    aptitude -y full-upgrade | tee $upgraded_packages >/dev/null
+    DEBIAN_FRONTEND=noninteractive aptitude -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" full-upgrade | tee $upgraded_packages >/dev/null

修正した処理の詳細

※chatGPTの回答なので信頼性は各自ご判断ください。

  1. DEBIAN_FRONTEND=noninteractive : DEBIAN_FRONTEND 環境変数に noninteractive を設定し、aptitude コマンドを非対話モードで実行します。これにより、パッケージの更新時に表示される確認メッセージを自動的に承認することができます。
  2. aptitude -y : aptitude コマンドに -y オプションを指定して、すべての質問に対して自動的に yes を返答するようにします。
  3. -o Dpkg::Options::="--force-confdef" : dpkg コマンドに --force-confdef オプションを指定して、パッケージがインストールされる際に必要なデフォルトの設定値を使用するように指定します。
  4. -o Dpkg::Options::="--force-confold" : dpkg コマンドに --force-confold オプションを指定して、既存のコンフィグファイルを保持するように指定します。
  5. full-upgrade : aptitude コマンドの full-upgrade オプションを指定して、すべてのパッケージを最新バージョンに更新します。
  6. | tee $upgraded_packages >/dev/null : 更新されたパッケージのリストを一時ファイルに保存します。パイプライン演算子 | を使用して、aptitude コマンドの出力を tee コマンドに送信し、同時に一時ファイルに書き込むように指定します。>/dev/null を追加することで、標準出力を無効化し、結果を表示しないようにします。

修正後のスクリプト全文

#!/bin/bash

# インストールされているパッケージの一覧を取得して別ファイルに出力します。
now1=$(date +%Y%m%d)
dpkg-query -W > installed_packages_$now1.txt

# aptitude updateを行います。
aptitude update

# updateの結果:
if aptitude search '~U' | grep -q '^i'; then
    # 対象パッケージ,変更前バージョン,変更後のバージョン を記入した日付付きのファイルを作成。
    now1=$(date +%Y%m%d)
    upgraded_packages=$(mktemp)

    # パッケージのキャッシュをクリアした上でパッケージアップグレードを実施。
    aptitude clean
    DEBIAN_FRONTEND=noninteractive aptitude -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" full-upgrade | tee $upgraded_packages >/dev/null

    # パッケージ一覧からの差分を別ファイルで作成。(実行日の日付を付与)
    new_packages=$(mktemp)
    dpkg-query -W > $new_packages
    diff -u installed_packages_$now1.txt $new_packages > package_diff_$now1.txt

   # 新しいパッケージ名を取得
   DIFF_FILE="package_diff_$now1.txt"
   NEW_PACKAGES=$(grep -E "^\+[^+]" $DIFF_FILE | awk '{print $1}' | cut -c 2-)

   # 変更されたパッケージの数と、新しいバージョンのパッケージ名のリストを表示
   UPDATED_PACKAGES=$(echo "$NEW_PACKAGES" | wc -l)
   echo "$UPDATED_PACKAGES 件のパッケージに変更がありました。以下のパッケージが更新されました:"
   echo "$NEW_PACKAGES"

    # 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
        # ファイル名に日付を追加
        now2=$(date +%Y%m%d)
        filename="restart_services_$now2.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

これでコンフィグを残すか否かのアップデートでも停止することなく動きましたが、肝心の

  • どのパッケージがコンフィグを残すか否か求められたか
  • その差分は何か

などが不明。なので、改善点はまだまだです。