ttt

getttyent

portsnapでwgetを使わせる

2006-01-28 22:58:52 | デジタル・インターネット

先日、

(FreeBSD) portsnapが暴走する?

と書いたように、phttpgetが暴走することはなくなりました。しかし、やはり、トラブルはまだ続いています。

どうもその場所のプロキシーサーバの動作が異常で、頻繁に、ファイルのダウンロードに失敗します。

ダウンロードに失敗しても、phttpgetってば、もう一度ダウンロードしようとしてくれません。こんなかんじでした。

  • portsは頻繁に更新されているので、1~2週間ぶりにportsnapを実行したところ、全部で1000個くらいのファイルをダウンロードしようとしました。
  • とうぜん、いくつかのファイルのダウンロードは失敗します。
  • もう一度portsnapを実行すると、すでにダウンロード済みのファイルも、もう一度ダウンロードしてるみたいです。
  • しかも、portsnapを実行すると、どのファイルをダウンロードすべきかを調べる処理をしているらしいんですが、この処理が、VMwareの中で実行するには、けっこう重い処理のようです。

というわけで、何回、何十回とportsnapを実行しても、いつまでたっても、portsnap fetchが成功しないのです。

というわけで、頭にきたので、phttpgetを改造することにしました。

・・・やめました。phttpgetってば、ソフトウェアとして完成度が低いです。

たとえば、データ読み出しのタイムアウト時間が15秒とか決めうち(hard coding)されてるんです。最近の流行で、プロキシーサーバでウイルスチェックとかやってる場合、全部プロキシーサーバまでダウンロードが終わって、ウイルスチェックが終わってから、クライアント(パソコン)へ一挙にデータ転送がはじまります(プロキシなしだと、水道からチョロチョロ水が流れるみたいなかんじになりますが、その余計なプロキシが挟まると、チョロチョロ水をバケツに一度ためて、一杯になってから一度にまく、みたいになる)。そういう場合、15秒でタイムアウトというのは、ちょっと短すぎます。

で、代替案が、ひらめきました。

phttpgetは捨てる。wgetで置き換える!

wgetというのは、HTTPやFTPでファイルをダウンロードするソフトで、昔からあるのでけっこう有名だと思います。/usr/ports/ftp/wgetとしてportsにもなっています。昔から使われているだけあって、ダウンロードに失敗したときの再実行もあるし、タイムアウト時間も自由に調整できます。

で、考えること、3分経過。こんなシェルスクリプトができあがりました。実質的に、重要な処理は最後の1行だけです。

#! /bin/sh

WGET=/usr/local/bin/wget

if [ $# -lt 2 ]
then
    echo "usage: $0 server [file ...]"
    exit 64
fi

SERVER=$1
shift

echo $* | tr ' ' '\n' | ${WGET} --base="http://${SERVER}/" --no-clobber --input-file=-

「phttpget-wget.sh」をダウンロード

phttpgetを置き換える例

  1. cp phttpget-wget.sh /usr/libexec/
  2. mv /usr/libexec/phttpget /usr/libexec/phttpget.org
  3. ln -s /usr/libexec/phttpget-wget.sh /usr/libexec/phttpget

このシェルスクリプトで、/usr/libexec/phttpgetを置き換えたところ、これまで何度やっても失敗していたportsnap fetchが、1発で成功しました。

唯一、phttpgetが優れているのは、HTTPのkeep aliveを使って、1回のコネクションで、複数のファイルをダウンロードしているところでしょうか。wgetもkeep aliveをサポートしているのですが、どうも上記のような用途では、keep aliveを使わないみたいです(リンクをたどって再帰的にダウンロードするときのみkeep aliveかな?)。

keep aliveを使うと、通信のオーバーヘッドが減るので、スループットが向上するのはわかりますが、そもそもphttpgetはそのほかの点で(エラー処理があまいなど)、ファイルをダウンロードするソフトウェアとして、致命的に欠点があります。

というわけで、その「いやがらせプロキシーサーバ」があるネットワーク環境では、phttpgetは捨てました。自宅では、phttpgetは快調に動いているんですけどね。

余談

シェルスクリプトのことを、

シェル

と省略して呼ぶ人がたまにいるんです。これ、すごく気持ち悪いです。省略するんだったら、

スクリプト

って呼ぶべきですよね。シェルと省略するのは、

ジャイアント・パンダを、ジャイアントと省略する

ようなものです。