AWKが便利すぎて泣ける

initramfsを使ってLVM上のパーティションをルートにしている。あまりにも素朴な自作initramfsにはfsckすらなかったのだが、500回以上もfsckなしでルートをマウントしていたという事実が判明。これではイカンということで、initramfsでfsckできるようにしようとした時に、AWKがすごく便利だった、というお題です。

さて、基本的には、e2fsckをinitramfsにコピーして、initスクリプトで呼びだせばよいだけなのだが、ここでひとつ問題が。e2fsckに必要なライブラリを全てinitramfsにコピーしなけりゃならない。

必要なライブラリは、lddを実行すれば得られる。

ldd /sbin/e2fsck

結果は、

	linux-vdso.so.1 (0x00007fffd6470000)
	libext2fs.so.2 => /lib64/libext2fs.so.2 (0x00007f316e2a2000)
	libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f316e09e000)
	libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f316de63000)
	libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f316dc5e000)
	libe2p.so.2 => /lib64/libe2p.so.2 (0x00007f316da56000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f316d6a6000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f316d489000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f316e4e7000)

ここで、/lib64/以下のライブラリを全てカレントディレクトリにコピーすればよいことにしよう。もちろん、いちいち手で入力するなんてやってられない。目当てのファイル名は1カラム目か3カラム目にあるので…

ldd /sbin/e2fsck | awk 'NF==2 {print $1}; NF>2 {print $3}'

結果は、

linux-vdso.so.1
/lib64/libext2fs.so.2
/lib64/libcom_err.so.2
/lib64/libblkid.so.1
/lib64/libuuid.so.1
/lib64/libe2p.so.2
/lib64/libc.so.6
/lib64/libpthread.so.0
/lib64/ld-linux-x86-64.so.2

一行目のlinux-vdso.so.1はカーネル内にあるからコピーする必要はない。それで、この出力をさらにawkを使って整形する。

ldd /sbin/e2fsck | awk 'NF==2 {print $1}; NF>2 {print $3}' | awk '/^\// {print "cp","-L",$0,"."}'

結果は、

cp -L /lib64/libext2fs.so.2 .
cp -L /lib64/libcom_err.so.2 .
cp -L /lib64/libblkid.so.1 .
cp -L /lib64/libuuid.so.1 .
cp -L /lib64/libe2p.so.2 .
cp -L /lib64/libc.so.6 .
cp -L /lib64/libpthread.so.0 .
cp -L /lib64/ld-linux-x86-64.so.2 .

あとは、これをbashにでも渡してやればok.

ldd /sbin/e2fsck | awk 'NF==2 {print $1}; NF>2 {print $3}' | awk '/^\// {print "cp","-L",$0,"."}' | /bin/bash

これを、一本のスクリプトで実現しようとすると、割と面倒臭いことになると思うんだけど、パイプとawkを使えば殆んどやりたい部分だけを記述すればok。非常にラク