Linux, macOSでPython, Ruby, Node.js, PHP, Apache, WordPress, jQueryの最新バージョン・ローカルバージョンを一括で取得・確認・比較するシェルスクリプト(バッチ処理プログラム) ~リリースバージョンとインストールされているバージョンの定期的なチェックで更新・アップデート対策~

2月 20, 2017AWS,EC2,jQuery,Node.js,PHP,Programming,Python,Ruby,Shell Script

LinuxやmacOSを使ったサーバー運用・開発環境の管理において、ソフトウェアのバージョン管理はセキュリティと安定性の両面から欠かせない作業です。Python、Ruby、Node.js、PHP、Apache HTTP Server、WordPress、jQueryなど、Webシステムを構成するコンポーネントはそれぞれ独自のリリースサイクルで更新され、脆弱性パッチや機能改善が随時提供されています。

しかし、これらのソフトウェアを個別に確認する作業は時間と手間がかかります。更新を見逃せば、CVE(Common Vulnerabilities and Exposures)データベースに登録された既知の脆弱性を抱えたまま運用を続けるリスクが生じます。特にWordPressやjQueryは攻撃対象として狙われやすく、Apache HTTP Serverも定期的なセキュリティリリースへの対応が重要です。

以前の記事「pyenv、rbenv、ndenvをシステム全体・システムワイドにインストールし、Python、Ruby、Node.jsのバージョンを使い分ける 〜Amazon Linux、CentOSで実行できる最新バージョンをインストールするシェルスクリプト(バッチ処理プログラム)〜」では、主要な言語環境の構築方法を解説しました。

本記事では、その応用として、1つのシェルスクリプトを実行するだけで7つのソフトウェアの最新リリースバージョンとローカルにインストール済みのバージョンを同時に確認・比較できるツールを実装し、詳細に解説します。cronによる定期実行の自動化まで含め、実際の運用環境ですぐに活用できる形で紹介します。

本スクリプトを活用することで得られる主なメリットは以下の通りです:

  • セキュリティリスクの早期検出:インストール済みバージョンと最新版の差分を一目で把握し、セキュリティパッチの適用漏れを防止
  • 複数ソフトウェアの一括管理:7つのコンポーネントを1回の実行でまとめて確認
  • クロスプラットフォーム対応:LinuxとmacOSの両方で動作する汎用性の高い実装
  • 自動化による運用工数の削減:cronと組み合わせることで手動チェックを不要化
  • 柔軟なカスタマイズ:監視対象ソフトウェアの追加・変更が容易な設計

対象ソフトウェアとバージョン管理の重要性

本スクリプトでは、Webシステム開発・運用で広く使用される以下の7つのソフトウェアを対象としています。各ソフトウェアのリリースサイクルとサポートポリシーを把握することで、適切なタイミングでのアップデート判断が可能になります。

プログラミング言語

  • Python:データサイエンス・機械学習(scikit-learn、TensorFlow、PyTorch等)、WebフレームワークのDjango・Flaskなど幅広い用途で採用。Python 2系は2020年1月1日をもってサポートを終了しており、Python 3系への移行が必須。マイナーバージョンでも新機能が追加される。
  • Ruby:Ruby on Railsを中心としたWebアプリケーション開発で広く普及。セキュリティフィックスを含むパッチリリースは速やかな適用が推奨される。RC版・preview版は本番環境への適用を避けること。
  • Node.js:サーバーサイドJavaScriptの実行環境。「Current版」(最新機能を含む開発者向け)と「LTS版」(Long Term Support、約30ヶ月の長期サポート)の2系統があり、本番環境ではLTS版の使用が強く推奨される。
  • PHP:WordPressをはじめ多くのCMSやWebアプリケーションのサーバーサイドで使用。EOL(End of Life)を迎えたバージョンはセキュリティ修正が提供されないため、常にアクティブサポート中のバージョンへの移行が不可欠。

ミドルウェア・ライブラリ

  • Apache HTTP Server:世界で最も広く使われているWebサーバーの1つ。本体(HTTPD 2.4系)に加え、依存するApache Portable Runtime(APR)、APR-UTIL、APR-ICONVのバージョンも合わせた管理が必要。
  • WordPress:世界のCMSシェア60%以上を占めるプラットフォーム。コア本体・プラグイン・テーマを狙った攻撃が多数報告されており、セキュリティリリースへの迅速な対応が特に重要。セキュリティのみのマイナー更新は自動適用機能もある。
  • jQuery:JavaScriptライブラリのデファクトスタンダード。現在は3.x系が推奨版。1.x・2.x系はセキュリティサポートが終了しており、XSSなどの脆弱性リスクがあるため、早急な3.x系への移行が求められる。

これらのソフトウェアは定期的にアップデートがリリースされ、セキュリティパッチや新機能が追加されます。特にセキュリティ関連のアップデートを見逃すと、システムが攻撃のリスクにさらされる可能性があるため、定期的なバージョンチェックは必須です。下表に各ソフトウェアのバージョン管理における主なポイントを整理します。

ソフトウェアリリースサイクル本番推奨バージョン特記事項
Pythonマイナー版 年1回程度最新安定版(3.x系)2系はEOL済み・即時移行
Rubyマイナー版 年1回程度最新安定版(RC・preview除く)パッチ版は随時リリース
Node.jsLTS版:約30ヶ月サポートLTS版(本番環境向け)Current版は開発・検証用途
PHPマイナー版 年1回程度アクティブサポート中の最新版EOL版はセキュリティ修正なし
Apache HTTPDパッチ版 随時2.4系の最新版APR・APR-UTILも合わせて管理
WordPressセキュリティ版 随時最新安定版自動更新機能の活用を推奨
jQuery不定期3.x系の最新版1.x・2.xはEOL済み

バージョン確認シェルスクリプトの実装

スクリプトの設計思想

このスクリプトは、実際のサーバー運用現場での使いやすさを最優先に、以下の設計方針で実装されています:

  1. 公式ソースからの直接取得:各ソフトウェアの公式サイトや公式ミラーサイトから直接バージョン情報を取得することで、情報の信頼性を担保
  2. 正規表現による堅牢なパース:curlで取得したHTMLをsed・grepで処理してバージョン番号を正確に抽出。HTMLの細かな構造に依存しない柔軟な正規表現を採用
  3. クロスプラットフォーム対応:改行コードの扱いなど、LinuxとmacOSの環境差異を考慮した実装により、どちらの環境でも同じスクリプトが動作
  4. リリース版とローカル版の並列表示:最新リリースバージョンとローカルにインストール済みのバージョンを並べて出力し、更新の必要性を一目で判断可能
  5. 安定版のみを対象:RC版・beta版・alpha版・preview版を正規表現フィルタで除外し、本番環境での使用に適した安定リリースのみを取得

バージョン抽出の共通パターン

スクリプト内では、各ソフトウェアに共通する以下の処理フローでバージョン番号を抽出しています。このパターンを理解することで、スクリプトの読解やカスタマイズが容易になります:

  1. curl でリリースページの HTML を取得(curl -sS URL
  2. バージョン番号を含む行を grep で絞り込み
  3. 数値とドット以外の文字を改行コードに置換(sed 's/[^0-9.]/'$LF'/g'
  4. 数値で始まる行のみ抽出(grep '^[0-9]'
  5. 先頭・末尾の余分なドットを削除
  6. 重複削除とソート(sort -n | uniq
  7. 対象のバージョン形式(X.Y または X.Y.Z)に一致するものを抽出

この共通パターンにより、新たなソフトウェアの監視追加も同じ手順で対応できます。

完全版シェルスクリプト

以下が実際に動作する完全版のシェルスクリプトです。各ソフトウェアのセクションにコメントを付けており、処理の流れが把握しやすくなっています:

[magtranetwork@localhost ~]# vim check_new_version.sh
#!/bin/bash

#===============================================================================
# スクリプト名: check_new_version.sh
# 説明: 主要なプログラミング言語・ミドルウェアの最新バージョンをチェック
# 対応環境: Linux, macOS
# 対象ソフトウェア: Python, Ruby, Node.js, PHP, Apache, WordPress, jQuery
#===============================================================================

#-------------------------------------------------------------------------------
# バージョン抽出の基本ロジック
#-------------------------------------------------------------------------------
# 各リリースサイトのHTMLから、以下の処理フローでバージョンを抽出します:
#
# 1. バージョンを含む行を取得
# 2. 数値とドット以外を改行に置換(sed 's/[^0-9.]/'$LF'/g')
# 3. 数値で始まる行のみ抽出(grep '^[0-9]')
# 4. 先頭・末尾のドットを削除(sed 's/^\.//g' と sed 's/\.$//g')
# 5. 重複を削除(sort -n | uniq)
# 6. バージョン形式に一致するものを抽出
#
# 例:
#   X.Y 形式: grep '^[0-9]*\.[0-9]*$'
#   X.Y.Z 形式: grep '^[0-9]*\.[0-9]*\.[0-9]*$'
#   両方: grep -e '^[0-9]*\.[0-9]*\.[0-9]*$' -e '^[0-9]*\.[0-9]*$'
#-------------------------------------------------------------------------------

# 改行コードの定義(Linux/macOS両対応)
LF=$'\\\x0A'

#===============================================================================
# Python バージョンチェック
#===============================================================================
echo "======================================"
echo "Python"
echo "======================================"

# pythonコマンドの存在確認
which python > /dev/null 2>&1
IS_PKG=$?
IS_PKG=`echo "${IS_PKG}" | sed 's/ //g' | sed 's/\t//g' | tr -d '\n'`

echo "[Released Versions]"
# Python 3系の最新バージョン取得
PYTHON3_LATEST=`curl -sS https://www.python.org/downloads/ | \
  grep "Download Python " | grep '\.tar' | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | grep ^3 | tail -n 1`
echo "  Python 3.x: ${PYTHON3_LATEST}"

# Python 2系の最新バージョン取得(メンテナンス終了に注意)
PYTHON2_LATEST=`curl -sS https://www.python.org/downloads/ | \
  grep "Download Python " | grep '\.tar' | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | grep ^2 | tail -n 1`
echo "  Python 2.x: ${PYTHON2_LATEST} (※2020年にサポート終了)"

echo ""
echo "[Local Version]"
if [ "${IS_PKG}" = "0" ]; then
  python --version
else
  echo "  Python is not installed"
fi
echo ""

#===============================================================================
# Ruby バージョンチェック
#===============================================================================
echo "======================================"
echo "Ruby"
echo "======================================"

which ruby > /dev/null 2>&1
IS_PKG=$?
IS_PKG=`echo "${IS_PKG}" | sed 's/ //g' | sed 's/\t//g' | tr -d '\n'`

echo "[Released Versions]"
# RC版やpreview版を除外して安定版のみ取得
RUBY_LATEST=`curl -sS https://www.ruby-lang.org/en/downloads/ | \
  grep "Ruby" | grep '\.tar' | \
  grep -v '\-rc' | grep -v 'preview' | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  Ruby: ${RUBY_LATEST}"

echo ""
echo "[Local Version]"
if [ "${IS_PKG}" = "0" ]; then
  ruby -v
else
  echo "  Ruby is not installed"
fi
echo ""

#===============================================================================
# Node.js バージョンチェック
#===============================================================================
echo "======================================"
echo "Node.js"
echo "======================================"

which node > /dev/null 2>&1
IS_PKG=$?
IS_PKG=`echo "${IS_PKG}" | sed 's/ //g' | sed 's/\t//g' | tr -d '\n'`

echo "[Released Versions]"
# Current版(最新機能を含むバージョン)
NODE_CURRENT=`curl -sS https://nodejs.org/en/download/current/ | \
  grep "Version" | grep "Latest" | grep "Current" | \
  sed 's/ //g' | sed 's// /g' | sed 's/<\/strong>/ /g' | \
  awk '{print $2}'`
echo "  Node.js Current: ${NODE_CURRENT} (最新機能版)"

# LTS版(長期サポート版)
NODE_LTS=`curl -sS https://nodejs.org/en/download/ | \
  grep "Version" | grep "Latest" | grep "LTS" | \
  sed 's/ //g' | sed 's// /g' | sed 's/<\/strong>/ /g' | \
  awk '{print $2}'`
echo "  Node.js LTS: ${NODE_LTS} (推奨:本番環境向け)"

echo ""
echo "[Local Version]"
if [ "${IS_PKG}" = "0" ]; then
  node -v
else
  echo "  Node.js is not installed"
fi
echo ""

#===============================================================================
# PHP バージョンチェック
#===============================================================================
echo "======================================"
echo "PHP"
echo "======================================"

which php > /dev/null 2>&1
IS_PKG=$?
IS_PKG=`echo "${IS_PKG}" | sed 's/ //g' | sed 's/\t//g' | tr -d '\n'`

echo "[Released Versions]"
# GitHubのタグからRC版、beta版、alpha版を除外して取得
PHP_LATEST=`curl -sS https://github.com/php/php-src/ | \
  grep 'href' | \
  grep '/php/php-src/tree/php-[0-9]*\.[0-9]*\.[0-9]*"' | \
  grep -v 'RC' | grep -v 'beta' | grep -v 'alpha' | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  PHP: ${PHP_LATEST}"

echo ""
echo "[Local Version]"
if [ "${IS_PKG}" = "0" ]; then
  php -v | head -n 1
else
  echo "  PHP is not installed"
fi
echo ""

#===============================================================================
# Apache HTTP Server バージョンチェック
#===============================================================================
echo "======================================"
echo "Apache HTTP Server"
echo "======================================"

# ダウンロードサイトの設定(環境に応じて変更可能)
# 日本の高速ミラーサイトを使用
HTTPD_REPO=https://ftp.jaist.ac.jp/pub/apache/httpd
APR_REPO=https://ftp.jaist.ac.jp/pub/apache/apr

which apachectl > /dev/null 2>&1
IS_PKG=$?
IS_PKG=`echo "${IS_PKG}" | sed 's/ //g' | sed 's/\t//g' | tr -d '\n'`

echo "[Released Versions]"

# HTTPD(Apache本体)
HTTPD_LATEST=`curl -sS ${HTTPD_REPO}/ | \
  grep tar.gz | grep href | grep httpd-2.4 | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  HTTPD (Apache本体): ${HTTPD_LATEST}"

# APR(Apache Portable Runtime)
APR_LATEST=`curl -sS ${APR_REPO}/ | \
  grep tar.gz | grep href | grep apr-[0-9] | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  APR: ${APR_LATEST}"

# APR-UTIL
APR_UTIL_LATEST=`curl -sS ${APR_REPO}/ | \
  grep tar.gz | grep href | grep apr-util-[0-9] | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  APR-UTIL: ${APR_UTIL_LATEST}"

# APR-ICONV
APR_ICONV_LATEST=`curl -sS ${APR_REPO}/ | \
  grep tar.gz | grep href | grep apr-iconv-[0-9] | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  APR-ICONV: ${APR_ICONV_LATEST}"

echo ""
echo "[Local Version]"
if [ "${IS_PKG}" = "0" ]; then
  apachectl -V | grep -E "Server version|Server built|APR"
else
  echo "  Apache is not installed"
fi
echo ""

#===============================================================================
# WordPress バージョンチェック
#===============================================================================
echo "======================================"
echo "WordPress"
echo "======================================"

# WordPressのインストールパス(環境に応じて変更)
WORDPRESS_PATH=/var/www/html/wp-includes/version.php

echo "[Released Versions]"
WP_LATEST=`curl -sS https://wordpress.org/download/ | \
  grep "Version" | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep -e '^[0-9]*\.[0-9]*\.[0-9]*$' -e '^[0-9]*\.[0-9]*$' | tail -n 1`
echo "  WordPress: ${WP_LATEST}"

echo ""
echo "[Local Version]"
if [ -f ${WORDPRESS_PATH} ]; then
  WP_LOCAL=`cat ${WORDPRESS_PATH} | grep '\$wp_version' | \
    sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
    sed 's/^\.//g' | sed 's/\.$//g' | \
    sort -n | uniq | \
    grep -e '^[0-9]*\.[0-9]*\.[0-9]*$' -e '^[0-9]*\.[0-9]*$'`
  echo "  WordPress: ${WP_LOCAL}"
else
  echo "  WordPress is not installed or path is incorrect"
  echo "  (Current path: ${WORDPRESS_PATH})"
fi
echo ""

#===============================================================================
# jQuery バージョンチェック
#===============================================================================
echo "======================================"
echo "jQuery"
echo "======================================"

# jQueryファイルのパス(環境に応じて変更)
JQUERY_PATH=/var/www/html/js/jquery.min.js

echo "[Released Versions]"

# jQuery 3.x系
JQUERY3_LATEST=`curl -sS https://code.jquery.com/ | \
  grep 'jquery-3.' | grep '.min.js' | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  jQuery 3.x: ${JQUERY3_LATEST} (推奨:最新版)"

# jQuery 2.x系
JQUERY2_LATEST=`curl -sS https://code.jquery.com/ | \
  grep 'jquery-2.' | grep '.min.js' | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  jQuery 2.x: ${JQUERY2_LATEST}"

# jQuery 1.x系
JQUERY1_LATEST=`curl -sS https://code.jquery.com/ | \
  grep 'jquery-1.' | grep '.min.js' | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  jQuery 1.x: ${JQUERY1_LATEST} (※レガシーブラウザ対応)"

echo ""
echo "[Local Version]"
if [ -f ${JQUERY_PATH} ]; then
  JQUERY_LOCAL=`cat ${JQUERY_PATH} | awk 'NR==1 {print}' | \
    sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
    sed 's/^\.//g' | sed 's/\.$//g' | \
    sort -n | uniq | \
    grep -e '^[0-9]*\.[0-9]*\.[0-9]*$' -e '^[0-9]*\.[0-9]*$'`
  echo "  jQuery: ${JQUERY_LOCAL}"
else
  echo "  jQuery is not installed or path is incorrect"
  echo "  (Current path: ${JQUERY_PATH})"
fi
echo ""

echo "======================================"
echo "Version check completed!"
echo "======================================"

スクリプトの実行方法と結果の見方

実行前の準備と権限設定

スクリプトを実行する前に、実行権限を付与してください。また、スクリプト内で使用する curl コマンドが利用可能であることを確認してください(macOS・主要なLinuxディストリビューションには標準搭載):

# 実行権限の付与
[magtranetwork@localhost ~]# chmod 755 check_new_version.sh

# スクリプトの実行
[magtranetwork@localhost ~]# ./check_new_version.sh

実行結果の例と見方

以下は実際の実行結果のサンプルです。各ソフトウェアについて [Released Versions](公式の最新リリースバージョン)と [Local Version](ローカル環境にインストール済みのバージョン)が並べて表示されます。両者を比較することで、アップデートが必要かどうかを即座に判断できます:

======================================
Python
======================================
[Released Versions]
  Python 3.x: 3.11.5
  Python 2.x: 2.7.18 (※2020年にサポート終了)

[Local Version]
Python 3.10.8

======================================
Ruby
======================================
[Released Versions]
  Ruby: 3.2.2

[Local Version]
ruby 3.1.0p0 (2021-12-25 revision fb4df44d16) [x86_64-linux]

======================================
Node.js
======================================
[Released Versions]
  Node.js Current: v20.8.0 (最新機能版)
  Node.js LTS: v18.18.0 (推奨:本番環境向け)

[Local Version]
v18.17.1

======================================
PHP
======================================
[Released Versions]
  PHP: 8.2.11

[Local Version]
PHP 8.1.12 (cli) (built: Oct 28 2022 17:39:43) (NTS)

======================================
Apache HTTP Server
======================================
[Released Versions]
  HTTPD (Apache本体): 2.4.58
  APR: 1.7.4
  APR-UTIL: 1.6.3
  APR-ICONV: 1.2.2

[Local Version]
Server version: Apache/2.4.54 (Unix)
Server built:   Jul 20 2023 15:32:01
APR: 1.7.0
APR-UTIL: 1.6.1

======================================
WordPress
======================================
[Released Versions]
  WordPress: 6.3.2

[Local Version]
  WordPress: 6.2.2

======================================
jQuery
======================================
[Released Versions]
  jQuery 3.x: 3.7.1 (推奨:最新版)
  jQuery 2.x: 2.2.4
  jQuery 1.x: 1.12.4 (※レガシーブラウザ対応)

[Local Version]
  jQuery: 3.6.0

======================================
Version check completed!
======================================

実行結果の見方のポイント:上記の例では、PythonはローカルがPython 3.10.8に対して最新版が3.11.5であることが分かります。同様に、WordPressがローカル6.2.2に対し最新6.3.2が出ていること、jQueryもローカル3.6.0に対し最新3.7.1が利用可能であることが確認できます。このようにリリース版とローカル版の差異が一目で分かるため、優先的に対応すべきアップデートを素早く特定できます。セキュリティパッチを含む更新(パッチバージョンの増加)は特に迅速な対応が求められます。

スクリプトのカスタマイズ方法

環境に応じた設定変更

スクリプト内の以下の変数は、サーバー環境に応じて変更する必要があります。特にWordPressとjQueryは実際のファイル配置パスに合わせて設定してください:

WordPressのパス

# デフォルト設定
WORDPRESS_PATH=/var/www/html/wp-includes/version.php

# カスタムパスの例
WORDPRESS_PATH=/home/username/public_html/wp-includes/version.php

jQueryのパス

# デフォルト設定
JQUERY_PATH=/var/www/html/js/jquery.min.js

# カスタムパスの例
JQUERY_PATH=/home/username/public_html/assets/js/jquery.min.js

Apacheダウンロードサイト

# 日本のミラーサイト(デフォルト)
HTTPD_REPO=https://ftp.jaist.ac.jp/pub/apache/httpd
APR_REPO=https://ftp.jaist.ac.jp/pub/apache/apr

# 別のミラーサイトの例
HTTPD_REPO=https://ftp.riken.jp/net/apache/httpd
APR_REPO=https://ftp.riken.jp/net/apache/apr

追加ソフトウェアの監視

スクリプトに他のソフトウェアのチェック機能を追加することも可能です。前述のバージョン抽出の共通パターンを使えば、任意のソフトウェアを監視対象に加えられます。以下はNginxを追加する例です:

# 例:Nginxのバージョンチェックを追加
echo "======================================"
echo "Nginx"
echo "======================================"

which nginx > /dev/null 2>&1
IS_PKG=$?

echo "[Released Versions]"
NGINX_LATEST=`curl -sS https://nginx.org/en/download.html | \
  grep "Stable version" | \
  sed 's/[^0-9.]/'$LF'/g' | grep '^[0-9]' | \
  sed 's/^\.//g' | sed 's/\.$//g' | \
  sort -n | uniq | \
  grep '^[0-9]*\.[0-9]*\.[0-9]*$' | tail -n 1`
echo "  Nginx: ${NGINX_LATEST}"

echo ""
echo "[Local Version]"
if [ "${IS_PKG}" = "0" ]; then
  nginx -v 2>&1 | cut -d'/' -f2
else
  echo "  Nginx is not installed"
fi
echo ""

定期実行の設定(cron)

バージョンチェックを手動で実施するだけでは見落としのリスクがあります。cronに登録して定期実行することで、アップデートの確認漏れを防ぎ、運用の自動化が実現できます。以下は代表的な設定例です:

# crontabの編集
crontab -e

# 毎週月曜日の午前9時に実行し、結果をメールで通知
0 9 * * 1 /path/to/check_new_version.sh | mail -s "Weekly Version Check Report" admin@example.com

# 毎日午前3時に実行し、ログファイルに出力
0 3 * * * /path/to/check_new_version.sh >> /var/log/version_check.log 2>&1

運用上の注意点とベストプラクティス

バージョンアップ時の注意事項

バージョンアップには種類があり、対応の優先度と手順が異なります。パッチバージョン(X.Y.Zの変更)はバグ修正・セキュリティ修正が中心で比較的安全に適用できます。マイナーバージョン以上の変更は新機能追加や非互換変更を含む場合があるため、慎重に対応してください。

  1. 互換性の確認:メジャーバージョンアップ(例:PHP 7.x → 8.x)時は、既存のコード・プラグイン・ライブラリとの互換性を必ず事前確認する。公式の移行ガイドや変更ログを参照すること。
  2. ステージング環境での事前テスト:本番環境への適用前に、ステージング環境で動作確認を実施する。特にWordPressのコア更新はプラグイン・テーマとの組み合わせ問題が発生しやすい。
  3. バックアップの事前取得:アップデート前には必ずデータベースとファイルの完全バックアップを取得する。復旧手順も事前に確認しておくこと。
  4. 段階的なロールアウト:複数台のサーバーがある場合は、1台ずつ順番に適用してシステム全体への影響を最小化する。
  5. メンテナンス時間帯の選択:ユーザーへの影響を最小限にするため、アクセスが少ない時間帯(深夜・早朝など)を選んで適用する。

セキュリティアップデートへの対応フロー

CVEが公開されたり、ソフトウェアのセキュリティリリースが行われた際は、以下の標準手順で迅速に対応してください。特にCVSSスコアが高い(7.0以上)脆弱性は緊急対応が必要です:

  1. リリースノートとCVE詳細で脆弱性の内容・影響範囲・CVSS重要度を確認
  2. 自社システムのバージョンが影響範囲に含まれるか評価(本スクリプトで把握済みのローカルバージョンを活用)
  3. 対応優先度を決定(緊急:CVSS 7.0以上 / 重要:4.0〜6.9 / 注意:4.0未満)
  4. ステージング環境でパッチ適用・動作確認を実施
  5. 本番環境へ適用(可能であれば低トラフィック時間帯に実施)
  6. 適用後の動作確認・ログモニタリング(少なくとも24〜48時間)
  7. アップデート記録(日時・バージョン・担当者・確認結果)を変更管理台帳に記録

推奨される継続的な監視体制

  • 自動定期チェック:本スクリプトをcronに登録し、週次または月次でバージョン確認を自動化。結果をメール通知することで見落としを防止。
  • 公式セキュリティ情報の購読:Python Security、Ruby Security、Node.js Security WG、PHP Security、Apache Security、WordPress Security などの公式セキュリティメーリングリストやRSSフィードを購読する。
  • 変更管理と記録:アップデート履歴(日時・変更内容・担当者)を記録し、問題発生時のロールバック計画を事前に準備する。
  • チーム内での情報共有:バージョンチェック結果と対応状況を定期的にチームで共有し、対応漏れを防ぐ。
  • EOLカレンダーの管理:各ソフトウェアのサポート終了(EOL)日程を把握し、余裕をもって後継バージョンへの移行計画を立てる。

トラブルシューティング

よくある問題と解決方法

1. curlコマンドがタイムアウトする

# タイムアウト時間を延長
curl -sS --connect-timeout 30 --max-time 60 https://www.python.org/downloads/

2. プロキシ環境での実行

# スクリプト先頭に追加
export http_proxy=http://proxy.example.com:8080
export https_proxy=http://proxy.example.com:8080

3. バージョン番号が正しく取得できない

Webサイトの構造が変更された可能性があります。以下のコマンドで実際のHTML構造を確認し、grepパターンを調整してください:

curl -sS https://www.python.org/downloads/ | grep -i "download python"

4. macOSでsedの動作がLinuxと異なる場合

macOSのsedはBSD版のため、GNU sedと動作が一部異なります。スクリプト内では改行コードを $'\x0A' で定義することでこの差異に対処しています。もし問題が発生した場合は gsed(GNU sed for macOS:brew install gnu-sedでインストール可能)を使用してください。

5. 「command not found: curl」と表示される

curlが未インストールの環境では、パッケージマネージャでインストールしてください:

# Amazon Linux / RHEL / CentOS系
sudo yum install curl

# Debian / Ubuntu系
sudo apt-get install curl

# macOS(Homebrewを使用する場合)
brew install curl

よくある質問(FAQ)

Q1. スクリプトの実行にroot権限は必要ですか?

バージョン確認だけであれば、root権限は不要です。ただし、ローカルバージョンの確認対象(Apache、PHP等)が特権ユーザーでのみアクセス可能なパスにインストールされている場合は、適切な権限が必要になることがあります。

Q2. 取得されるバージョン情報はリアルタイムですか?

はい、スクリプト実行時に各ソフトウェアの公式サイトへcurlでアクセスしてリアルタイムにバージョン情報を取得します。そのため、インターネット接続が必要です。

Q3. 企業のファイアウォール内環境で使用できますか?

直接インターネットに接続できない環境では、「トラブルシューティング」の「2. プロキシ環境での実行」を参考にhttp_proxy/https_proxy環境変数を設定してください。外部サイトへのアクセス自体がポリシーで禁止されている場合は、スクリプトをネットワーク境界外のジャンプサーバー等で実行することをご検討ください。

Q4. Node.jsのCurrent版とLTS版はどちらを使うべきですか?

本番環境では必ずLTS版を選択してください。Current版は最新機能を含みますが、LTS版に昇格するまでの短期間しかサポートされません。LTS版は約30ヶ月の長期サポートが提供され、セキュリティパッチも継続的に提供されます。開発環境での新機能の評価目的であれば、Current版を使用することもあります。

Q5. WordPress以外のCMSには対応していますか?

本スクリプトはWordPressを対象としていますが、他のCMSも同様のパターンでカスタマイズ可能です。「スクリプトのカスタマイズ方法」セクションのパターンを参考に、対象CMSの公式リリースページに対応したcurl+grepの処理を追加してください。

まとめ

本記事で紹介したシェルスクリプトを活用することで、以下のメリットが得られます:

  • 7つのソフトウェアの一括バージョン管理:Python・Ruby・Node.js・PHP・Apache・WordPress・jQueryを1回の実行でまとめて確認
  • セキュリティリスクの早期発見と迅速対応:最新版との差分を可視化し、パッチ適用の優先度判断を効率化
  • 運用工数の大幅削減:cronによる自動化で手動確認の手間をなくし、通知機能で対応漏れを防止
  • クロスプラットフォームの汎用性:LinuxとmacOSの両方で使用可能
  • 拡張性の高い設計:Nginxや他のソフトウェアも同じパターンで監視追加が容易

定期的なバージョンチェックは、セキュアで安定したシステム運用の基本です。本スクリプトをベースに、環境に合わせてカスタマイズし、cronへの登録・通知設定まで含めた運用フローとして組み込んでください。バージョン管理の自動化は、セキュリティインシデントリスクの低減と運用品質の向上に直結します。

また、バージョン管理と合わせて、冒頭で紹介した「pyenv、rbenv、ndenvを用いた環境構築」も参考にしていただくことで、より効率的な開発・運用環境を構築できます。

Reference: Tech Blog citing related sources