«前の日記(2013-10-23) 最新 次の日記(2013-11-05)» 編集

meta's blog - The Power To Serve

筆者について

FreeBSDを通じてOSSにささかな貢献を。

OSS活動をご支援いただける方を募集しています


2013-10-30 yum コマンドの出力は grep してはいけない (grep するには向いていない)

yum コマンドの出力は grep してはいけない (grep するには向いていない)

grep してはいけないわけではないですが、yum コマンドの出力は grep するには向いていません。

普段は FreeBSD ばかりで久々に Linux を触っていたらハマったので備忘のために。

yum コマンドは RHEL 系の Linux ディストリビューションで、パッケージをあれやこれやするためのコマンドですが、とても人にやさしくできているために、人がそのまま目で見る以外の用途、シェルスクリプトの中で加工したり grep したりするなど、機械的に出力を扱う用途には相性が良くないです(こういうのをグレッパビリティが低いと一部では言うらしいが実際には聞いたことがない)。

例えば、インストール済みのパッケージを表示するために yum list installed を実行すると、以下のように出力されます。 人間が目で見る分にはカラムが縦にきっちり揃っていて見やすいですが、長いパッケージ名のものがあると2行に分かれてしまいます。

$ yum list installed
device-mapper-event-libs.x86_64  1.02.77-9.19.amzn1                    installed
device-mapper-libs.x86_64        1.02.77-9.19.amzn1                    installed
device-mapper-persistent-data.x86_64
                                 0.1.4-1.2.amzn1                       installed
dhclient.x86_64                  12:4.1.1-34.P1.18.amzn1               installed
dhcp-common.x86_64               12:4.1.1-34.P1.18.amzn1               installed

yum は端末の大きさに合わせて出力を調整してくれるので、1行に収めるためには端末の横幅を大きくすればいいのですが、これは端末に出力するのに限った話でパイプやリダイレクトで端末以外の物に出力すると、横幅が80桁固定になります。

sed や tr を使って出力を加工して強引に1行にすることもできます が、めんどくさいし美しくないです。

$ yum list installed | tr "\n" "#" | sed -e 's/# / /g' | tr "#" "\n"
device-mapper-event-libs.x86_64  1.02.77-9.19.amzn1                    installed
device-mapper-libs.x86_64        1.02.77-9.19.amzn1                    installed
device-mapper-persistent-data.x86_64                                 0.1.4-1.2.amzn1                       installed
dhclient.x86_64                  12:4.1.1-34.P1.18.amzn1               installed
dhcp-common.x86_64               12:4.1.1-34.P1.18.amzn1               installed

なんとかならないかと調べていたら grep するなら yum の代わりに repoquery を使うといいよRedHat の Bugzilla に書いてあるのを見つけました。

repoquery コマンドは柔軟に出力形式を指定できるので、シェルスクリプトなどで機械的に扱うのに向いています。 yum list installed 相当のものが欲しければ、以下のようにオプションを指定します。

$ repoquery --all --pkgnarrow=installed --qf="%{name}.%{arch}  %{version}-%{release}  %{repo} | tail -n4 | tee installed-packages.txt
yum-plugin-upgrade-helper.noarch  1.1.31-17.16.amzn1  installed
yum-utils.noarch  1.1.31-17.16.amzn1  installed
zip.x86_64  3.0-1.10.amzn1  installed
zlib.x86_64  1.2.7-10.17.amzn1  installed

awk などで真ん中のバージョンだけを切り出しやすい出力が得られます。

$ <installed-packages.txt awk '{ print $2 }'
1.1.31-17.16.amzn1
1.1.31-17.16.amzn1
3.0-1.10.amzn1
1.2.7-10.17.amzn1

アップデート可能なパッケージを得るために yum check-update 相当の出力が欲しければ --pkgnarrow=updates と置き換えれば OK です。

$ repoquery --all --pkgnarrow=updates --qf="%{name}.%{arch}  %{version}-%{release}  %{repo} | tail -n4
rpm-python.x86_64  4.11.1-3.49.amzn1  amzn-updates
system-release.noarch  2013.09-1.0  amzn-updates
udev.x86_64  173-4.12.amzn1  amzn-updates
yum.noarch  3.4.3-111.46.amzn1  amzn-updates

というわけで、「yum はパッケージのインストールやアンインストールなどの操作と、人間が目で見るための出力を得るもの。スクリプトで加工するときには repoquery を使う。」と覚えておけばいろいろ捗ります。

本日のツッコミ(全1件) [ツッコミを入れる]
Σ はしも (2018-09-03 11:07)

%{repo} の直後に " が必要?