KITA Eng.

北海道でサーバー技術者として歩み出したひとが綴るblog。

Windowsでchecksumを調べる---FCIVを利用してみた

「ファイル チェックサム整合性検証 (FCIV) ユーティリティ」を使ってみました。 特に深い理由はありません。GIMPさんをインストールするときに徐に、ダウンロードファイルのMD5チェックサムでも一応確認しようかとふと思い立っただけです。

FCIVですが、

FCIV ユーティリティは、Microsoft Windows 2000Windows XP、および Windows Server 2003 上で実行されます。
https://support.microsoft.com/ja-jp/kb/841290

なんてあって、ドキュメントの最終更新が2011/09/10のようなので、古くからあるツールの模様。

手元のWindows10では、公式ドキュメントのインストールの項目どおりに作業すれば問題なく動きました。コマンドプロンプトからでももちろんPowrShellからでも問題ないようです。

チェックサムを計算
PS C:\Users\Kastuay\Downloads> fciv.exe .\gimp-2.8.16-setup-4.exe
//
// File Checksum Integrity Verifier version 2.05.
//
3dbad964d5fe1d2a065bc9cbea0ee1a0 .\gimp-2.8.16-setup-4.exe

md5ないし、sha1でのハッシュ値を計算できるようで、特定のディレクトリ下を再帰的に確認して、xmlで出力するなんてこともできるんだとか。

ディレクトリ下の各ファイルのチェックサムを計算して、xml形式ファイルに出力
PS C:\Users\Katsuya\Downloads> fciv.exe -r .\sumtest\ -xml sumtest.xml
//
// File Checksum Integrity Verifier version 2.05.
//
Start Time: 06/11/2016 at 12h40'36''

Error loading XML document.
Create New XML database

End Time..: 06/11/2016 at 12h40'37''


        Processed 1 directories
        Processed 2 files
Errors have been reported to fciv.err
出力したXMLファイルの内容からチェックサム結果を表示
PS C:\Users\Katsuya\Downloads> fciv.exe -list -xml .\sumtest.xml
//
// File Checksum Integrity Verifier version 2.05.
//
Listing entries in database:
----------------------------

                MD5                             Filename
-------------------------------------------------------------------------
acc0db27eed709ecb25e5369fb8cfd87 .\sumtest\FileZilla_3.13.1_win64.zip
3dbad964d5fe1d2a065bc9cbea0ee1a0 .\sumtest\gimp-2.8.16-setup-4.exe
チェックサムと一致するか確認する。
PS C:\Users\Katsuya\Downloads> fciv.exe -v -xml .\sumtest.xml
一致
PS C:\Users\Katsuya\Downloads> fciv.exe -v -xml .\sumtest.xml
//
// File Checksum Integrity Verifier version 2.05.
//
Could not create the registry key.
Starting checksums verification : 06/11/2016 at 12h54'37

All files verified successfully

End Verification : 06/11/2016 at 12h54'37
不一致

一方のZIPファイルの中身をちょっといじってみた。

PS C:\Users\Katsuya\Downloads> fciv.exe -v -xml .\sumtest.xml
//
// File Checksum Integrity Verifier version 2.05.
//
Could not create the registry key.
Starting checksums verification : 06/11/2016 at 12h55'58

List of modified files:
-----------------------
.\sumtest\FileZilla_3.13.1_win64.zip
        Hash is         : acc0db27eed709ecb25e5369fb8cfd87
        It should be    : ea4684909453db52c7d4fa3105bdcd8e

End Verification : 06/11/2016 at 12h55'58
XMLの中身

チェックサムの結果は、Base64エンコードされて格納される仕様だそうだ。なのでXMLを直接ただ見ただけだとチェックサムの値はわからない。

Base64デコードするか、FCIVの-listオプションを使ってプロンプト上で見る必要がある模様。 f:id:kacchan822:20160611125121p:plain


ユーティリティ説明資料

Windows10の環境変数を設定する画面が親切になっていた。

Windowsを使っていてほとんど触る機会はないけど、ちょっとマニアックな何かをインストールしてみたりするときとかに、必要になる環境変数の操作。変にいじってしまったら大事件が起きるんじゃないか感が強いわりに、UIが結構使いにくくて、間違わないかいじるたびに冷や冷やしていた覚えがあった。

Win32 OpenSSHを、快適に使おうと久々に環境変数の画面を開いたら、劇的に変わっていてびっくり。

ここは今まで通り。

f:id:kacchan822:20160607211109p:plain

ここもほぼ今まで通り?

f:id:kacchan822:20160607211401p:plain

ここが素晴らしい

いままで、自分でセミコロンで区切って値を入れていたわけですが、値が一行ごとに分かれています。 f:id:kacchan822:20160607211059p:plain

自作マシンとかでSSD&HDD構成にしたときに、SSDの寿命を慮ってTEMPファイルの書き出し先をシステムドライブにしたSSDじゃなくてHDDにするとかでよく使った、TEMPの値変更の部分に至っては、よくあるファイルを選択する画面のUIになっていて、変なパスを指定してしまう事件が起こりづらくなっています。 f:id:kacchan822:20160607212633p:plain


ちょっと感動して、記録がてら書いてからググったら先人がいました。変更点もまとまってます。ほほー。 hiiragi.hateblo.jp

続・SSHクライアントといえば?

こんな記事を書いてから早半年以上が経過していました。 kitaeng.hateblo.jp

Windows 10だとなんだかPoderosaがうまく動いてくれなかったり、Ubuntuのターミナルでも自動でコマンドログを取る方法もググったら意外とたくさん出てきて、何とかなったので、すっかりPoderosaは使わなくなった今日この頃です。

この間、WindowsSSHクライアント環境に新兵器たちが現れ始めましたようです。ざっくり言ってしまうと、まだ、正式リリースになっていないものたちなので、実用性的には微妙な感じだけど、今後に期待というところ。

WindowsBashが?

だいぶ盛り上がりは去った感がありますが、今夏に予定されているWindows10の大型アップデート「Anniversary Update」の新機能の1つとして、「Bash on Windows」が話題に上って、ちょっと選択肢が増えたかもな状況でありました。(かくいう自分もこの新機能が気になって、Windows10のマシンをInsiderPreviewでアップデートするように設定を変えました。そして、直後にうまく起動しなくなるという事件に見舞われました...)

 これ-->鈴木淳也の「Windowsフロントライン」:Windows 10で動く「Bash」を試す Mac使いの開発者にもアピールする? (1/3) - ITmedia PC USER

PowershellにOpenSSHが移植されていた

すっかり冒頭の記事を書いている時には気が付いていませんでしたが、冒頭の記事を書いている時にはすでに、pre-release版で、「Win32 OpenSSH」なるものが、公開されていたようです。

 これ --> WindowsでOpenSSHを使ってSSHサーバーの起動と接続をする方法~PowerShell編 - Qiita  MSDNのblogにも記事になってた --> OpenSSH for Windows Update | Windows PowerShell Blog

開発はもりもり進んでいるようで、今夏ぐらいにはOpenSSHの本家の方にくっつくのを目指しているのだとか。昨冬に出たばかりのころは、.ssh/configファイルなんかが使えなくて...だったようですが、ここのところのアップデートで、configファイルは利くようになった模様。 github.com

普通にsshする分には、結構便利。何せ、gitからダウンロードしてきて、設置したPATHを環境変数に追加すればいいだけだから、WindowsBashより楽ちん(そりゃ、Bashの方はssh以外にもいろいろできちゃうんだから当たり前か...)。設定が悪いのか、ssh先でvimとか、topとか使うと画面表示が崩れるので、メイン使用にはできそうにない。設定をいじればなんとかなるんだろうか。

Cronの自動処理を多重起動させないための方法を調べたら...。

photo by mag3737

 Cronで定期的に実行さている処理が、システム負荷だったり処理する量の変化によって、実行間隔よりも長くかかってしまうと、多重起動するという小事件が発生するのです。

 多重起動しても大して影響のないようなものならいいんですけ、多重起動によって余計にシステム負荷が増大したり、多重で実行されることでうまく動かないなんてこともあったりするわけで...。

 必要に迫られたので、その解決方法をいろいろと探ってみました。

ひとまずGoogle先生に問い合わせると...

 上のようなところが現れました。

 大雑把にまとめると、

  1. ロックファイルをつくる
  2. プロセスの存在を確認する

という手段のもよう。まぁ、そうなりますよね...。

どう実装するか(方針)

 ロックファイルをつくるのが良いのか、プロセスの存在を確認するのが良いのか…。

 異常終了でロックファイルがうまく解放されないとか削除されないという事件が起こると悲しいことになるということで、プロセスの存在確認の方向で進むことにしました。

 プロセスの存在確認の方法もいくらか考えようがあって、

  1. pidファイルを用意して、起動時にpidを書き込む
  2. 現在稼働中のプロセスから拾う

とかがよく出てくるやつのようですが、1.はロックファイル同様ファイルの書き込みが発生するので、ロックファイルを却下した後に選択するのは...。ということで、2.現在稼働中のプロセスから拾う作戦でいくことにしました。

現在稼働中のプロセスから拾う作戦の実装

 いくつか候補が上がったので、ひとまず列挙。(以下、対象となるCronで実行するスクリプト名を、"cron_job.sh"という名称ということにします。)

  1. ps -ef | grep -E "[c]ron_job.sh"
  2. pgrep -fo cron_job.sh
  3. pidof -x cron_job.sh

 プロセスがあるかどうか拾うといえばpsと思ってましたが、他にもpgrepとかpidofなんてコマンドもいらっしゃったのですね。

1. ps -ef | grep -E "[c]ron_job.sh"

 プロセスの存在確認でよく見る気がする書き方ですが、おまじない的にgrep正規表現なんぞ使っていてうっとおしいので、却下とします。いや、別に正規表現が嫌いとかじゃないんだよ、謎の[ ]の意味を思い出すのがめんどくさいんだよ...。

2. pgrep -fo cron_job.sh

 Man page of PGREP

 -fオプションを使うことで、プロセス名だけではなくて、コマンドライン全体をマッチ対象にできる。これをつけるかつけないかがちょっとした分かれ目。

 cronで実行するスクリプトに実行権限をつけて実行させている場合は、-fなしでよさそうだけど、phpスクリプトとかで、/usr/bin/php /path/to/script/cron_job.phpみたいにcronで呼んでいると、cron_job.phpの部分は-fなしだとマッチしてくれないもよう(/usr/bin/phpの引数として与えられているだけの値という扱いだからだろう)。

 とりあえず-fつけときゃいいんじゃねと思いつつ、ちょっとした落とし穴もあって、-fをつけるとコマンドライン全体がマッチ対象になって、部分一致でも引っかかる。あまりないかもだけど、cron_job.shでマッチさせようとしたのに、cron_job.sh.v2とか謎のやつも動かしてたりすると...。多くの場合はほとんど気にならないパターンでしょうか。

 プロセスの抜出はこいつでうまくいきそうなので、実際に多重起動を防ぐ形でのcronへの登録は、

10 * * * * user if [ "$$" = "`pgrep -fo cron_job.sh`" ]; then /path/to/script/cron_job.sh; fi

こんな形としました。最初はは、testの部分を"" = "pgrep -fo cron_job.sh"としていたのですが、うまく動かず。cronで呼ばれた時点でpgrepには自分がマッチする状況になっているので、空にはならないということなんでしょう。一番古いpidと自分のpidが一致すれば自分しか起動していないという、判断をするという形にしました。

 ということで、今回は一応これで解決としました。

3. pidof -x cron_job.sh

 Man page of PIDOF

 2.で解決したので、こっちの検証はいらなかった気もしないでもないですが...。せっかくなので勉強がてらこっちでの方法も検討しました。

 こちらは、「名前でプロセスを見つけ、それらの PID を一覧表示する」というコマンドということで、2.の検証でちょっと問題に上った、

 cronで実行するスクリプトに実行権限をつけて実行させている場合は、-fなしでよさそうだけど、phpスクリプトとかで、/usr/bin/php /path/to/script/cron_job.phpみたいにcronで呼んでいると、cron_job.phpの部分は-fなしだとマッチしてくれないもよう(/usr/bin/phpの引数として与えられているだけの値という扱いだからだろう)。

が影響します。こいつで実装する場合は、スクリプトに実行権限を与えておいてあげて、直接実行してあげる形にする必要があるようです。

 で、このパターンで実際に多重起動を防ぐ形でのcronへの登録は、

10 * * * * user pidof -x cron_job.sh >/dev/null || /path/to/script/cron_job.sh

 こっちはすっきりしました。コマンドライン全体がマッチ条件にならないこと、指定したコマンドのプロセスがひとつも見つからなければ、0以外のリターンコードを返すを利用すると、ifを使わずに||を使ってあげれば、すっきり書けるもようです。

 cronで実行するスクリプト自体に実行権限がついているなら、こっちのほうが良いかもしれません。

雑感

 今回は、ファイルを読み書きせずに、既存のスクリプトには手を加えずに、なんか追加でインストールしたりせずにという条件の中での実装となったので、こんな感じです。  Google先生に尋ねているときにちらほら見かけたのは、あんまり間隔の短いスパンで動かすならデーモン化...みたいなこともあったりしたので、そういう方向もあるんでしょうねぇ。  よく使うコマンドをひたすらパイプで組み合わせていく作戦もいいんですけど、結構、要件にマッチしたコマンドって埋もれているもんだなぁと思ったのでありました。

whoisの情報から必要なところだけを抜き出してくれるようにしてみた。

何かとwhoisipアドレスを引いて情報を確認することが多いのですが、フォーマットのバラバラ具合にまいります。たいてい使うのは、当該IPを含むネットワークアドレスと国コードぐらい。これだけ出てくれればいいんす。なんてことを思って、早数カ月。別件で、探し物をしていたらPythonのパッケージに、ipwhoisなるものがあるのを発見しました。

なんかいい感じに必要なデータだけを抜き出すのに便利そうだったのでちょこっと書いてみました。

Simple Whois --> swhoisとか名付けてみた

ご自由にどうぞ。ただし、動作保証はできません。

実行例
user@localhost:~/$ ./swhois.py 122.226.102.60
122.226.102.60 --> 122.226.102.0/24 CN

引数に調べたいipを与えてあげると、whoisで調べて出てきた一番細かいCIDRで区切られたネットワークと国コードを返してくれます。

ipaddressモジュールを使用している関係で、python 2.x系では動きません。ipaddressモジュールを使わなくても実現できる気がしますが、ipaddressモジュールはとても便利なので無駄遣いしてしまします。