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。非常にラク。