ディスクイメージファイル(.dmg)をコマンドラインから
13th December 2016Macでたくさんのファイルをひとまとめにするのであればzipで圧縮するよりも、ディスクイメージファイルにしたほうが便利なこともあります。zipだと標準では中身を確認するのに毎回どこかに展開しないといけないですし、ファイルの内容を変更するのも面倒です。zip用のツールを使えばおそらくそれらも解決できると思いますが、個人的にはディスクイメージファイル(.dmg)を使うことの方が多いです。
ディスクイメージファイルは外付けディスクのようなイメージでマウントして使えます。macOSに標準添付されている「ディスクユーティリティー」ツールを使えばこのイメージファイルを簡単に作ることができます。読み取り専用、読み書き可能、暗号化、圧縮などオプションを選ぶこともできます。
終了したプロジェクトのファイル一式は.dmgファイルとしてまとめていますが、まとめたいプロジェクトファイルがたくさんあったり、ワークフローを自動化したいとなってくるとコマンドライン操作を覚えると便利です。
ディスクイメージファイルの作成
hdiutil
コマンドを使うとディスクイメージファイルの作成や設定変更、ディスクイメージファイルのマウント、アンマウントなどさまざま操作可能です。詳しくはman hdiutil
をご参照いただくとして手元での利用例をご紹介します。
フォルダ以下にあるサブフォルダをそれぞれ.dmg
として一括変換したい場合に使っているスクリプトです。それぞれ一応暗号化しておこうということで、暗号化用のパスワードを$HOME/.dmg-password
というファイルにあらかじめ格納してあります。パスワードファイルには最後に改行が入らないようにつくっておいてください。
あとパーミッションも chmod 600 $HOME/.dmg-password
など他者から読み出せないようにしておきます。そうはいっても、後述しますが一連のプロセスはさほど安全性が高いわけではありませんので「添付ファイルはパスワードつきzipでパスワードは別メールですぐ送信!」とあまり変わらないセキュリティーレベルとお考えいただいていいかと思います。
#!/bin/sh
if [ $# -lt 2 ]; then
echo $0 SRC_DIR DEST_DIR
exit 1
fi
SRC=$1
DST=$2
PWD="$HOME/.dmg-password"
if [ ! -e $PWD ]; then
echo Disk Image password not found
exit 2
fi
for t in "$SRC"/*; do
if [ -d "$t" ]; then
echo Creating: $t
n=$(basename $t)
cat $PWD | \
hdiutil create \
-srcfolder "$t" \
-fs HFS+ \
-encryption AES-128 \
-format UDBZ \
-stdinpass \
"$DST/$n.dmg"
fi
done
ディスクイメージファイルのパスワードをKeyChainにプリセットしておく
暗号化しておいたのはいいですが、作成したディスクイメージファイルを開く際にいちいちパスワードを入力するのは面倒です。Finderからダブルクリックしてマウントしようとしたときに聞かれるパスワードダイアログはコピー&ペーストを受け入れてくれないというのもさらに面倒さを増しています。
パスワードをキーチェインに記憶させるというオプションがありますが、あらかじめコマンドラインから記憶させておけばいいという発想です。
ディスクイメージファイルに対するパスワードは一般パスワードとして各ディスクイメージファイルのUUIDと対応して管理されています。このUUIDは
$ hdiutil isencrypted ディスクイメージファイル.dmg
というようにisencrypted
オプションで知ることができます。キーチェインにパスワードを追加するには
$ security add-generic-password -a (上記のUUID) -D "disk image password" -s (ファイル名).dmg -w (パスワード)
というように実行すればよいでしょう。security
コマンドの大変残念な点はhdiutil
の-stdinpass
のように標準入力からパスワードを受け取る手段がどうやらなさそうな点です。
コマンド引数として実行してしまうと、シェルの履歴に残ったり、ps
コマンドなどでパスワードが漏えいしてしまうケースがあります。このような点から上述のように「添付ファイルはパスワードつきzipでパスワードは別メールですぐ送信!」というセキュリティーレベルとたいして変わらないと思っています。
さて、上記を合わせて次のようなスクリプトにしてあります。
#!/bin/sh
if [ $# -lt 1 ]; then
echo $0 [dmg file]...
exit 1
fi
PWD=$HOME/.dmg-password
for FILE in "$@"; do
UUID=$(hdiutil isencrypted "$FILE" 2>&1 | grep uuid | awk '{print $2}')
BASE=$(basename $FILE)
echo File: $BASE
echo UUID: $UUID
security add-generic-password -a $UUID -D "disk image password" -s $BASE -w $(cat $PWD)
done
このようにキーチェインにパスワードを設定したファイルを開こうとすると次のようにキーチェインからパスワードを取り出していいか確認されます。
このダイアログをsecurity
コマンドの-A
オプションでスキップする手段もありますがすべてのアプリケーションに対して許可を出してしまいます。少し面倒ですが、ここは一手間かけておいたほうがいいでしょう。