499.status-pkgupdate を改造してみる

map page を見ろと言っておきながらあまり map page が好きじゃない cocelo です。ごきげんよう
よくわかんない出だしですが、たまにはこういうのもいいかなと。
と言う訳で、今回は 499.status-pkgupdate を改造してみます。


まずは下記がその原文です。

#!/bin/sh
#
# $Id: 499.status-pkgupdate,v 1.2 2005/08/01 02:15:07 ueda Exp $
#

# If there is a global system configuration file, suck it in.
#
if [ -r /etc/defaults/periodic.conf ]
then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

export PATH=$PATH:/usr/local/sbin:/usr/local/bin
export LANG=C

[ ! -x /usr/local/sbin/portsnap ] && exit 0

echo
echo "Ports/packages update check:"
(portsnap cron && portsnap update) >/dev/null 2>&1

if [ $? -eq 0 ]; then
	portsdb -u >/dev/null 2>&1
	portversion -vL=
	rc=0
else
	echo "Failure of portsnap(*ERROR*)"
	rc=1
fi
echo

exit $rc


実はこのシェルスクリプト、 6.0R ( 及び 6.1R ) を新規インストールした人は使えません。
というのは、 6.0R から標準で portsnap が付いてくるようになったので、 /usr/local/sbin/portsnap には存在しません。
多分 /usr/local/sbin/portsnap は ports で入れた場合に存在すると思うのですが、私は 6.0R と 6.1R しか使ったことがないのでわかりません。


ということで、まずは該当個所を見てみます。
下記がその該当個所です。

export PATH=$PATH:/usr/local/sbin:/usr/local/bin

[ ! -x /usr/local/sbin/portsnap ] && exit 0


これを書き換える訳ですが、ただ /usr/local/sbin を /usr/sbin に置き換えてしまっては芸が無いので、下記のように書き換えてみました。

export PATH=$PATH:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin

[ ! -x /usr/sbin/portsnap ] && [ ! -x /usr/local/sbin/portsnap ] && exit 0


ただ、これだとどちらにも portsnap が存在する場合、 /usr/sbin/portsnap が実行されるのか、 /usr/local/sbin/portsnap が実行されるのかわからないので、下記のように書き換えてみます。

#!/bin/sh
#
# $Id: 499.status-pkgupdate,v 1.2 2005/08/01 02:15:07 ueda Exp $
#

# If there is a global system configuration file, suck it in.
#
if [ -r /etc/defaults/periodic.conf ]
then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

export PATH=$PATH:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
export LANG=C

if [ -x /usr/sbin/portsnap ]; then
	echo
	echo "Ports/packages update check:"
	(/usr/sbin/portsnap cron && /usr/sbin/portsnap update) >/dev/null 2>&1

	if [ $? -eq 0 ]; then
		/usr/local/sbin/portsdb -u >/dev/null 2>&1
		/usr/local/sbin/portversion -vL=
		rc=0
	else
		echo "Failure of portsnap(*ERROR 01*)"
		rc=1
	fi
	echo

	exit $rc

elif [ -x /usr/local/sbin/portsnap ]; then
	echo
	echo "Ports/packages update check:"
	(/usr/local/sbin/portsnap cron && /usr/local/sbin/portsnap update) >/dev/null 2>&1

	if [ $? -eq 0 ]; then
		/usr/local/sbin/portsdb -u >/dev/null 2>&1
		/usr/local/sbin/portversion -vL=
		rc=0
	else
		echo "Failure of portsnap(*ERROR 02*)"
		rc=1
	fi
	echo

	exit $rc

else
	echo "Failure of portsnap(*ERROR 03*)"
	exit 0
fi


しかし、実は上記の portsnap update の記述は man page で使わないように書いてあります。
portsnap(8)

Running portsnap update from cron(8) is a bad idea -- if you're ever
installing or updating a port at the time the cron job runs, you'll
probably end up in a mess when portsnap updates or removes files
which are being used by the port build.  However, running portsnap -I
update is probably safe, and can be used together with portversion(1)
to identify installed software which is out of date.


上記では portsnap update ではなく、 portsnap -I update を使うように、と書いてあるので該当個所を下記のように書き換えました。

	(/usr/sbin/portsnap cron && /usr/sbin/portsnap -I update) >/dev/null 2>&1

及び、

	(/usr/local/sbin/portsnap cron && /usr/local/sbin/portsnap -I update) >/dev/null 2>&1


上記の記述を反映させたのが下記になります。

#!/bin/sh
#
# $Id: 499.status-pkgupdate,v 1.2 2005/08/01 02:15:07 ueda Exp $
#

# If there is a global system configuration file, suck it in.
#
if [ -r /etc/defaults/periodic.conf ]
then
    . /etc/defaults/periodic.conf
    source_periodic_confs
fi

export PATH=$PATH:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
export LANG=C

if [ -x /usr/sbin/portsnap ]; then
	echo
	echo "Ports/packages update check:"
	(/usr/sbin/portsnap cron && /usr/sbin/portsnap -I update) >/dev/null 2>&1

	if [ $? -eq 0 ]; then
		portsdb -u >/dev/null 2>&1
		portversion -vL=
		rc=0
	else
		echo "Failure of portsnap(*ERROR 01*)"
		rc=1
	fi
	echo

	exit $rc

elif [ -x /usr/local/sbin/portsnap ]; then
	echo
	echo "Ports/packages update check:"
	(/usr/local/sbin/portsnap cron && /usr/local/sbin/portsnap -I update) >/dev/null 2>&1

	if [ $? -eq 0 ]; then
		portsdb -u >/dev/null 2>&1
		portversion -vL=
		rc=0
	else
		echo "Failure of portsnap(*ERROR 02*)"
		rc=1
	fi
	echo

	exit $rc

else
	echo "Failure of portsnap(*ERROR 03*)"
	exit 0
fi


以上でシェルスクリプトは完成です。
次回はこのシェルスクリプトを periodic で on or off の指定が出来るように改造してみたいと思います。


余談ですが、 id:hiro-ueda 様が雑誌の取材を受けたそうです。

いつもお世話になっている 技術評論社 さんからのご提案で、来月号の SoftwareDesign 誌の『IT エクスプローラ』(掲載予定)の取材を受けました。
いつもの担当の O 氏、副編集長さんに加え、ONGS の杉山さんもご来社いただき、1時間ほど Dr.WEB を中心とした話しをさせていただきました。

とりあえず近場の本屋に SoftwareDesign という雑誌を置いているかどうか聞いてみたところ、扱っていないとのこと。orz
なんとか手に入れたいので取り寄せてもえないか聞いてみたら、微妙な反応が・・・。 orz
Amazon で探してみようかな。