AIDEMOIRE

【アイデモワール】

ステータス表示機能付きdd

よく使うUNIX系のコマンドに“dd”があります。DVDからISOファイルを作るにも、HDDをコピーしたりデータを書き込んだりするにも、何かと便利なコマンドです。特にブロックサイズ(一度に読み書きするデータサイズ)を指定できるので、大きなサイズのファイルやデバイスの操作に向いています。

そんなお気に入りのコマンドのddなのですが、一つ不満を言えば、今どれくらいのデータを処理したのかが分かりにくいことです。大きなファイルやデバイスをコピーするのに使うので数時間に渡って動かくことがありますから、進捗状況を見れた方が精神的にも嬉しいです。

ddには“SIGUSR1”というシグナルを受け取ると、現在の進行状況を端末に出力するという機能があります。これを使えば進捗を確認できるのですが、そのためには、別のウィンドウ(もしくは別の端末)からpsコマンドでddのプロセスIDを確認して、必要に応じてsudoしてからkillコマンドを打つ必要があります。面倒くさいですね。

そこで、“ddv”というシェル スクリプトのコマンドを作りました。中でddを起動するのですが、その前に定期的にddに対してシグナルを送る別プロセスを生成します。引数はddと全く同じです。ddvの引数はそのまま全てddに引き渡します。従って、使い方はddと同じです。

デフォルトでは180秒毎に途中経過を出力するようにしています。ddvの引数はddの引数になってしまうため、間隔の調整は環境変数“DDV”で行います。デフォルトの180秒毎でよければ次のように使います。

ddv if=/dev/zero of=16G bs=1G count=16

間隔を60秒にしたい場合は次のようにしてddvを起動します。

env DDV=60 ddv if=/dev/zero of=16G bs=1G count=16

簡単なシェルスクリプトですから、プログラムを改造してもいいですし。

プログラムは [Bash] ddv - Pastebin.com *1 に置いてあります。/usr/local/bin などにコピーして使います。

こんなラッパー コマンドを使わなくてもddにそうしたパラメータを追加してくれると便利なのですが....。

細かいところについてのコメント

*ddが終了した際、sleepプロセスが残ってしまいます

Ctrl-Cによる中断なども含めてddが終了した後もシグナル送信用プロセスが起動したsleepが残ってしまいます。特に実害はありませんし、時間が来ればsleepは終了しますが、ちょっとスマートではないなと思っています。

*Ctrl-Cを受け付けるようにddをフォアグランドで動かしています

このプロセスはddをフォアグランドで動かしています。 ddをバックグラウンドで、シグナル送信用プロセスをフォアグランドで、もしくは両方バックグラウンドでという方法もあったのですが、bash(shでも同じ)のシェルスクリプトからバックグラウンド ジョブに対してはSIGINT(Ctrl-Cを押したときに送られるシグナル)がブロックされます。ddを中断させるだけならSIGINT以外の多くのシグナル(例えば、SIGHUPとかSIGTERMとか)でも中断できます。しかし、ddはSIGINTをを受け付けつけた時に限って最後にステータスを表示してから止まります。それ以外のシグナルでは何の情報も表示せずに止まります。ということで、必然的にはddはフォアグランドで動かすことになります。シェルスクリプトからバックグラウンドのジョブに対してSIGINTを送れるようなオプションをあれば、もう少しスマートな実装にできるのですが。

*1:真面目なサイトなんですが、たまに怪しげな広告が出ます。多分、サイトを運用している外人さんにはどんな広告なのかわからないのでしょう。自由に使えるのでリーク情報のような怪しい情報もたまにあるそうですが....。