Arch Linuxをいつものように使っていて、あるときいくつかのアプリケーションが動かないことに気がつきました。
今回は動かなかったfcitx5を代表例として、ターミナルから起動させてみました。
$ fcitx5-configtool
Cannot mix incompatible Qt library (5.15.5) with this library (5.15.6)
[1] 41884 IOT instruction (core dumped) fcitx5-configtool
互換性のない Qt ライブラリ (5.15.5) をこのライブラリ (5.15.6) と混在させることはできません。
どうやら、Qt5のライブラリに5.15.(5|6)が混在するせいで、うまく動かないようです。
ですので、Qt5のライブラリで5.15.6をグレードダウンさせて、5.15.5に統一することで解決します。
TL;DR
解決手段として、AURにdowngradeというツールがありますので、そちらを使用します。
また、ダウングレードするパッケージ量が多いので、パッケージの指定方法をワンラインで解決してみました。
paru -S downgrade # downgradeをAURヘルパーでインストールします。
paru -Qs qt5 | rg '5.15.6' | sed -r "s/local\///g" | awk -F'[ ]' '{print $1}' | tr '\n' ' ' > pkglist.txt && sudo downgrade `cat pkglist.txt` && rm pkglist.txt
今回のコマンドで、注意してほしいこと。
- AURヘルパーには
paruを使用していますが、ほかのAURヘルパーでも問題なく動くかと思います。 -
downgradeでのダウングレードバージョンの指定方法は、fzfでインクリメントサーチすることになるので、パッケージの数だけ都度指定する必要があります。 -
downgradeではダウングレードしたパッケージをpacman.confのIgnorPkgに追加する機能もありますが、コマンド終了後にpacman.confを確認した方が良いです。-
IgnorePkgへの指定されているパッケージリストが以下のように酷いことになります。コマンドが終了したら、削除することをお勧めします。
-
あとは、ワンラインで何をやっているのかの解説になります。
よろしければ最後までお付き合いください。
downgradeについて
Arch Linuxにおけるパッケージ管理ツールであるpacmanは最新のパッケージの更新のみで、ダウングレードやバージョン指定のインストールなどには対応していません。
もし不具合などでパッケージのダウングレードをしたい場合は、インストール時に/var/lib/pacman/local下へキャッシュされるパッケージをsudo pacman -Uを使用して解決できます。
そのうえで/etc/pacman.confのIgnorePkgへ、更新を無効にするパッケージ名を追記することでダウングレードが完了します。
このダウングレード作業が1~2回くらいならどうってことはないのですが、10を超えてくると作業量はたいへんなものになってしまいます。
それをお手軽にパッケージ指定して解決できるのが、このdowngradeです。
処理的にはpacmanをラップして、ローカルキャッシュとALA(Arch Linux Archive)と呼ばれるオンラインで保管されている過去バージョンのパッケージをfzfで検索してダウングレードを行います。
ダウングレード完了後はインタラクティブにIgnorePkgへ追記するか確認してくれるので、必要であればyを選択して追記してもらいましょう。
今回はダウングレードするパッケージをすべてIgnorePkgへ追記してもらいました。
対象のパッケージを絞り込む
pacmanやそれをラップしているAURヘルパーでは-Qsでインストール済みのパッケージを検索できます。
今回はタイプ量が減るのでparuから検索してみました。
その検索結果にはデフォルトで、以下のようなフォーマットで出力されます。
local/パッケージ名 パッケージバージョン パッケージグループ
パッケージ説明
この検索結果を標準入力でripgrepに渡して、検索対象のバージョンを指定します。
これはgrepでも可能ですね。皆さんもターミナルで検索するときは良くやると思います。
$ paru -Qs qt5 | rg '5.15.6'
local/qt5-base 5.15.6+kde+r184-1 (qt qt5)
local/qt5-doc 5.15.6-1 (qt qt5)
local/qt5-examples 5.15.6-1 (qt qt5)
⋮
⋮
⋮
これでparuからの検索結果をバージョン指定して、パッケージリストの一行目のパッケージ名やバージョンが書いてある部分だけのリストを取得できました。
必要なところだけを抽出して整形する
とりあえず、local/の部分は不要ですので、sedコマンドを使用してここを削除してしまいましょう。
$ paru -Qs qt5 | rg '5.15.6' | sed -r 's/local\///'
qt5-base 5.15.6+kde+r184-1 (qt qt5)
qt5-doc 5.15.6-1 (qt qt5)
qt5-examples 5.15.6-1 (qt qt5)
⋮
⋮
⋮
こんな風に出力されたと思います。
あと欲しいのはスペースで区切られた最初の部分ですので、awkコマンドを使用して1フィールド目のパッケージ名を抽出します。
$ paru -Qs qt5 | rg '5.15.6' | sed -r 's/local\///' | awk -F '[ ]' '{print $1}'
qt5-base
qt5-doc
qt5-examples
⋮
⋮
⋮
downgradeに引数として渡す
pacmanだと、<を使用して先ほどまでの処理できたリストの形式でファイル読み込みができます。
同じようにdowngradeでもできると思ったのですが、どうやら駄目みたいです。
とりあえず改行がない状態にして、ファイルリストをスペースで区切られた形に整形して引数として渡せるようにしてみます。
$ paru -Qs qt5 | rg '5.15.6' | sed -r "s/local\///g" | awk -F'[ ]' '{print $1}' | tr '\n' ' '
qt5-base qt5-doc qt5-examples …
ここからいろいろ試して、標準入力でdowngradeの引数に渡そうとしたのですが、うまくいきませんでした。
ですのでリダイレクトでファイルを作成してしまって、それをコマンド置換を使用してcatで出力したものを引数に渡すという方法に落ち付きました。
paru -Qs qt5 | rg '5.15.6' | sed -r "s/local\///g" | awk -F'[ ]' '{print $1}' | tr '\n' ' ' > pkglist.txt && sudo downgrade `cat pkglist.txt` && rm pkglist.txt
ここまでの出力内容をリダイレクトでpkglist.txtを作成し、downgradeに引数で渡すのはcatコマンド置換でファイル内容を出力させます。
これでdowngradeにファイルリストを渡せたのでdowngradeの処理が終了したあとに、作成してしまったpkglist.txtを削除すればワンラインとしてのコマンドは終了です。
あとは冒頭で説明した通りpacman.confのIgnorePkgがすごいことになるので、コメントアウトされたIgnorePkgの部分を削除すれば完全に終了です。
そんな感じにTwitterで困っていたら、「xargsを使えば解決できるのでは?」というアドバイスをもらったのですが、こちらも完全解決にはなりませんでした。
パッケージをダウングレードするかの確認と、ダウングレード後のIgnorePkgへの追加確認で使用される部分は標準入力で呼び出されると正常に処理できないようです。
まとめ
やはりLinuxでターミナル操作をメインにしていると、(Vim|Neovim)でのテキスト編集が一番フィットすると思います。
さらに言えば、ワンラインで一気に処理されるのはカッコイイですよね!
ただ、最後まで標準入力を使用するパイプで簡潔できなかったのは悔しいところですね…。
ワンラインという操作は今回が、ほとんど初めてみたいな感じだったので拙いところがあったかもしれません。
こうするとできるかも、みたいなコメントがあれば歓迎します。
ここまでお読みいただきありがとうございました。
