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

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

以前の記事でPython, Ruby, Node.jsをpyenv、rbenv、ndenvでインストールする手順と最新のバージョンを常にインストールするシェルスクリプト(バッチ処理プログラム)を紹介しました。

参考記事:「pyenv、rbenv、ndenvをシステム全体・システムワイドにインストールし、Python、Ruby、Node.jsのバージョンを使い分ける 〜Amazon Linux、CentOSで実行できる最新バージョンをインストールするシェルスクリプト(バッチ処理プログラム)〜

上記で紹介したPython, Ruby, Node.jsやPHP, Perlなどのプログラミング言語は新機能の追加やセキュリティ脆弱性の修正などの開発が行われ、安定したタイミングで新しいバージョンがリリースされています。

また、Apache, NginxなどのWebサーバのミドルウェア、WordPress, Movable TypeなどのCMS製品、jQuery, Prototype JavaScript FrameworkなどのJavaScriptライブラリも同様の理由で新しいバージョンが次々とリリースされているのが現状です。

このようにオープンソースのソフトウェアを用いたシステム開発にバージョンアップは付き物ですが、常にアンテナを張って各モジュールのバージョンアップ情報を収集していないと、セキュリティ脆弱性の修正などの重要なアップデートを見逃してしまします。

今回はそんな常に情報を収集しておくべき最新バージョンアップ情報をローカルのモジュールのバージョンと合わせて取得・確認・比較する方法を紹介します。

以下で紹介するシェルスクリプト(バッチ処理プログラム)は数あるプログラミング言語やミドルウェアの中でもWEB開発でよく使われているPython, Ruby, Node.js, PHP, Apache, WordPress, jQueryを対象に最新バージョンを確認する仕様となっています。

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

オープンソースの各ソフトウェアの最新バージョンはインターネットの公式ウェブサイト、ミラーサイト、Githubなどで入手することができます。

今回紹介する方法は各ソフトウェアの最新バージョンのモジュールを実際にダウンロードできるサイトから最新バージョン情報を正規表現を用いて取得します。

Linux, macOSでPython, Ruby, Node.js, PHP, Apache, WordPress, jQueryの最新バージョン・ローカルバージョンを一括で取得・確認・比較するシェルスクリプト(バッチ処理プログラム)

下記が実際に最新バージョンを取得・確認・比較するサンプルのシェルスクリプト(バッチ処理プログラム)です。

基本方針としてはシェルスクリプト(バッチ処理プログラム)の冒頭コメントに記載のとおり、ソフトウェアのバージョンの形式に一致する正規表現で抽出します。

Linux, macOSの両方に対応するように実装しているため、改行コードの処理に文字コードを指定した「LF=$’\\\x0A’」やスペース、タブ文字の除去処理等を入れています。

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

#各リリースサイトHTMLのバージョンを含む行から下記のような正規表現を用いたコマンドでバージョンの取得を行う。
#具体的には数値以外の文字列を改行し、そこから数値から始まる文字列のみを対象にバージョンの正規表現で対象文字列を抽出する。
#LF=$'\\\x0A'
#[バージョンを含む行を表示する処理] | sed 's/[^0-9.]/'"$LF"'/g' | grep '^[0-9]' | sed 's/^\.//g' | sed 's/\.$//g' | sort -n | uniq | grep '^[0-9]*\.[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]*$'
#[バージョンを含む行を表示する処理] | 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]*$'

#sedで改行コードへの置換に使用する。
LF=$'\\\x0A'

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

#リリースされているPythonの最新バージョンの取得、ローカルのPythonのバージョンの取得をして表示する。
#Pythonについてはバージョン2、バージョン3を取得する。
echo "***Python***"
echo "[Released]"
RES=`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`
echo "Python3: ${RES}"
RES=`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`
echo "Python2: ${RES}"
echo "[Local]"
if [ "${IS_PKG}" = "0" ]; then
  python --version
else
  echo ""
fi
echo ""

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

#リリースされているRubyの最新バージョンの取得、ローカルのRubyのバージョンの取得をして表示する。
echo "***Ruby***"
echo "[Released]"
RES=`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: ${RES}"
echo "[Local]"
if [ "${IS_PKG}" = "0" ]; then
  ruby -v
else
  echo ""
fi
echo ""

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

#リリースされているNode.jsの最新バージョンの取得、ローカルのNode.jsのバージョンの取得をして表示する。
#Node.jsについてはCurrentバージョン、LTSバージョンを取得する。
echo "***Node.js***"
echo "[Released]"
RES=`curl -sS https://nodejs.org/en/download/current/ | grep "Version" | grep "Latest" | grep "Current" | sed 's/ //g' | sed 's/<strong>/ /g' | sed 's/<\/strong>/ /g' | awk '{print $2}'`
echo "Node.js Current: ${RES}"
RES=`curl -sS https://nodejs.org/en/download/ | grep "Version" | grep "Latest" | grep "LTS" | sed 's/ //g' | sed 's/<strong>/ /g' | sed 's/<\/strong>/ /g' | awk '{print $2}'`
echo "Node.js LTS: ${RES}"
echo "[Local]"
if [ "${IS_PKG}" = "0" ]; then
  node -v
else
  echo ""
fi
echo ""

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

#リリースされているPHPの最新バージョンの取得、ローカルのPHPのバージョンの取得をして表示する。
echo "***PHP***"
echo "[Released]"
RES=`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: ${RES}"
echo "[Local]"
if [ "${IS_PKG}" = "0" ]; then
  php -v
else
  echo ""
fi
echo ""

#HTTPD, APRのダウンロードサイトを指定する。
#好みによってミラーサイトを変更する。
HTTPD_REPO=https://ftp.jaist.ac.jp/pub/apache/httpd
APR_REPO=https://ftp.jaist.ac.jp/pub/apache/apr

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

#リリースされているApacheの最新バージョンの取得、ローカルのApacheのバージョンの取得をして表示する。
#ApacheについてはHTTPD, APR, APR-UTIL, APR-ICONVのバージョンを表示する。
echo "***Apache***"
echo "[Released]"
RES=`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]*$'`
echo "HTTPD: ${RES}"
RES=`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]*$'`
echo "APR: ${RES}"
RES=`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]*$'`
echo "APR-UTIL: ${RES}"
RES=`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]*$'`
echo "APR-ICONV: ${RES}"
echo "[Local]"
if [ "${IS_PKG}" = "0" ]; then
  apachectl -V | grep ":"
else
  echo ""
fi
echo ""

#WordPressのバージョンファイルのパス。
#環境に応じてパスを変更する。
WORDPRESS_PATH=/var/www/html/wp-includes/version.php

#リリースされているWordPressの最新バージョンの取得、ローカルのWordPressのバージョンの取得をして表示する。
echo "***WordPress***"
echo "[Released]"
RES=`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: ${RES}"
echo "[Local]"
if [ -f ${WORDPRESS_PATH} ]; then
  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]*$'
else
  echo ""
fi
echo ""

#jQueryのパス。
#環境に応じてパスを変更する。
JQUERY_PATH=/var/www/html/js/jquery.min.js

#リリースされているjQueryの最新バージョンの取得、ローカルのjQueryのバージョンの取得をして表示する。
#jQueryについてはバージョン1、バーンジョン2、バージョン3を表示する。
echo "***jQuery***"
echo "[Released]"
RES=`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]*$'`
echo "jQuery 3.x: ${RES}"
RES=`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]*$'`
echo "jQuery 2.x: ${RES}"
RES=`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]*$'`
echo "jQuery 1.x: ${RES}"
echo "[Local]"
if [ -f ${JQUERY_PATH} ]; then
  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]*$'
else
  echo ""
fi
echo ""

Linux, macOSでPython, Ruby, Node.js, PHP, Apache, WordPress, jQueryの最新バージョン・ローカルバージョンを一括で取得・確認・比較するシェルスクリプト(バッチ処理プログラム)の実行例

[mag4j@localhost ~]# chmod 755 check_new_version.sh
[mag4j@localhost ~]# ./check_new_version.sh
***Python***
[Released]
Python3: 3.6.0
Python2: 2.7.13
[Local]
Python 3.6.0

***Ruby***
[Released]
Ruby: 2.4.0
[Local]
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]

***Node.js***
[Released]
Node.js Current: v7.5.0
Node.js LTS: v6.9.5
[Local]
v7.5.0

***PHP***
[Released]
PHP: 7.1.1
[Local]
PHP 7.1.1 (cli) (built: Jan 1 2017 00:00:00) ( ZTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

***Apache***
[Released]
HTTPD: 2.4.25
APR: 1.5.2
APR-UTIL: 1.5.4
APR-ICONV: 1.2.1
[Local]
Server version: Apache/2.4.25 (Unix)
Server built:   Jan 1 2017 00:00:00
Server's Module Magic Number: 20120211:67
Server loaded:  APR 1.5.2, APR-UTIL 1.5.4
Compiled using: APR 1.5.2, APR-UTIL 1.5.4
Architecture:   64-bit
Server MPM:     event
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)

***WordPress***
[Released]
WordPress: 4.7.2
[Local]
4.7.2

***jQuery***
[Released]
jQuery 3.x: 3.1.1
jQuery 2.x: 2.2.4
jQuery 1.x: 1.12.4
[Local]
3.1.1

Reference: Tech Blog citing related sources