文字列の先頭や末尾を0埋めする方法はよくあるんですが、ファイル末尾を0データで埋める方法って、なかなか見つからなかったので、書いてみました。
こんなの一体いつ使うのか? と聞かれたら、使う機会は早々ないのであまり役に立たないかもしれないです(・_・; が、例えばinitramfsイメージファイルをLinuxカーネルのページサイズでalignしたい場合に役立ちます。
…絶対使わなそうですが、以下のようなスクリプトを書いてtest.shとして保存しておき、test.sh target.bin 4096
のように実行すれば、target.binの後に0データを付加して4096バイトでalignしてくれます。
#!/bin/bash
FILE_TARGET=${1}
SIZE_PAGE=${2}
function get_file_size() {
FILE=${1}
echo $(LANG=C ls -l ${FILE} | cut -d' ' -f5)
}
function get_printf_format() {
SIZE_PAD=${1}
while [ ${SIZE_PAD} -gt 0 ]; do
FORMAT=${FORMAT}'%b'
BIN=${BIN}'?x0'
let SIZE_PAD--
done
echo ${FORMAT} ${BIN}
}
MASK=$((${SIZE_PAGE} - 1))
SURPLUS=$(($(get_file_size ${FILE_TARGET}) & ${MASK}))
if [ ${SURPLUS} -ne 0 ]; then
printf $(get_printf_format $((${SIZE_PAGE} - ${SURPLUS}))) >> ${FILE_TARGET}
fi
例えば以下のようなサイズのファイルがあったとします。10進で99472バイトのデータです。
~ $ ls -l target.bin
-rw-r--r-- 1 pi pi 99472 Jul 31 00:01 target.bin
~ $ printf "0x%x?n" $(ls -l target.bin | cut -d' ' -f5)
0x18490
これに先ほどのスクリプトを実行してやると、以下のようになります。
~ $ ./test.sh target.bin 4096
~ $ ls -l target.bin
-rw-r--r-- 1 pi pi 102400 Jul 31 00:04 target.bin
~ $ printf "0x%x?n" $(ls -l target.bin | cut -d' ' -f5)
0x19000
~ $ hexdump -C target.bin | tail -n 4
00018480 75 74 69 6c 73 2e 73 79 73 63 6f 6e 66 69 67 0a |utils.sysconfig.|
00018490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00019000
しっかりと、4096 (0x1000)バイトでalignされたデータファイルになりました。これでとある機器のLinuxカーネルがパニックすることなく起動できます。
ぜひお試しあれ。
ただ、先ほどのスクリプト、get_printf_format
関数内の処理がかなり非効率なので、もっといい案あればぜひ教えてください(^人^)