試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

ddコマンドで/dev/zeroからファイルを作成する作業をGUIで実行

ファイルとしての形を持ったスワップや、仮想マシンのraw形式の仮想ハードディスクイメージ*1を作成するときなど、ファイルのサイズだけを確保するのに、ddコマンドを使用して

$ dd if=/dev/zero of=[出力ファイル] bs=[ブロックサイズ] count=[ブロック数]

といった形で作成作業を行うことがある。
この類の作業をGUIのみで行う方法が見当たらなかったので、Zenityを使用して出力ファイルの場所とサイズを指定するだけの簡単操作で楽に「0で埋められたファイル」を作成できるようなスクリプトを作成した。もちろん、進行状況も表示され、途中の取り消しもできる。
[任意]ファイル名: zerofille.sh

#! /bin/bash

# zerofille.sh (C) 2008 kakurasan
# Licensed under GPL-3
# 内容が全て「0」のファイルを作成するGUI(Zenity使用)

# 一時ファイル(1MiBもしくは8MiBのブロック)
TMPFILE=/tmp/zerofille-tmp

# 出力ファイルの場所を指定
OUTFILE=$(zenity --file-selection --save --confirm-overwrite --title "名前を付けて保存")
[[ ${?} -ne 0 ]] && exit 1  # キャンセルされたら何もしないで終了

# サイズの指定
# 正しい書式で入力されなければ入力ダイアログに戻る
for ((;;)); do
  SIZE=$(zenity --entry --title "サイズの指定" --text "ファイルのサイズを入力してください
例: 4g(4GiB)/100m(100MiB)/5000k(5000KiB)/512(512B)")
  [[ ${?} -ne 0 ]] && exit 1  # キャンセルされたら終了
  # 書式が正しければループを抜ける
  if echo ${SIZE} | egrep "^[0-9]+[kmg]?$" >/dev/null 2>&1; then
    break
  else
    zenity --error --title "書式が不正" --text "サイズの書式が不正なため
もう一度入力し直す必要があります"
  fi
done

# 「k」「m」「g」の部分のみを取り出す
UNIT=$(echo ${SIZE:$((${#SIZE} - 1))} | tr -d '[:digit:]')
# バイト単位の指定はそのまま書き出して終了
if [[ -z "${UNIT}" ]]; then
  dd if=/dev/zero of=${OUTFILE} bs=${SIZE} count=1
  exit 0
fi
case ${UNIT} in
 k)
  # KiB単位の指定の場合もそのまま書き出して終了
  dd if=/dev/zero of=${OUTFILE} bs=1k count=${SIZE/k/}
  exit 0
  ;;
 m)
  # MiB単位の指定では1MiBのブロックをddで作成後繰り返し結合
  COUNT=${SIZE/m/}
  dd if=/dev/zero of=${TMPFILE} bs=1M count=1
  ;;
 g)
  # GiB単位の指定では8MiBのブロックを使用して1GiB当たり128ブロックを繰り返し結合
  # 1024[MiB/GiB] = 8[MiB/Block] * 128[Block/GiB]
  COUNT=$((${SIZE/g/} * 128))    # ^^^^^^^^^^^^^^
  dd if=/dev/zero of=${TMPFILE} bs=1M count=8
  ;;
esac

# 出力ファイルに書き込めるかどうかをチェック
if ! echo "" > ${OUTFILE}; then
  zenity --error --title "書き込み失敗" --text "ファイル \"${OUTFILE}\" の書き込みに失敗しました"
  # 失敗したら一時ファイルを消して終了
  rm ${TMPFILE} -f
  exit 1
fi
rm ${OUTFILE} -f
# 進行状況を表示しながらブロックファイルを繰り返し追記していく
for ((I = 0; I < ${COUNT}; I++)); do
  echo $((100 * ${I} / ${COUNT}))              # パーセンテージをzenityに送る
  eval "cat \"${TMPFILE}\" >> \"${OUTFILE}\""  # 追記処理
done | zenity --progress --title "ファイル作成中" --text "ファイル \"${OUTFILE}\" ($(echo ${SIZE} | tr "[:lower:]" "[:upper:]")iB) を作成しています..." --auto-close || rm "${OUTFILE}" -f
rm ${TMPFILE} -f

# スワップファイルとして初期化できるようにする
if zenity --question --title "スワップファイルとしての初期化" --text "このファイルを
スワップファイルとして初期化することができます。
初期化しますか?"; then
  /sbin/mkswap ${OUTFILE}
fi

(2008/10/29)ファイル作成後、選択によりmkswapスワップファイルとして初期化ができるようにした(下の数行を追加)

ファイルサイズの入力

進行状況表示(MiB単位もしくはGiB単位の指定時)

関連記事:

*1:ディスク上に書き込まれるものと全く同じ形式