Ubuntu で Main リポジトリ以外のインストール済みパッケージを一覧にする

以下のコマンドを使用すると、 Ubuntu にインストールされているパッケージのうち、Main リポジトリ以外(Restricted, Universe, Multiverse)に属するものを一覧で表示できる。

dpkg-query --show --showformat='${binary:Package}\n' | xargs -IX bash -c "apt-cache policy X | sed -n --regexp-extended '1h;/.*(\/restricted|\/universe|\/multiverse) .*/{x;p;x;p;Q}'"

以上!

…とすると、この記事だけでは少し物足りない気がするので、使い方についても少し説明しておく。

なぜ Main リポジトリ以外のものを把握したいのか?

パッケージの取得元リポジトリのカテゴリを把握する理由は、Canonical による Ubuntu Pro のサポート範囲が関係しているからだ。

apt コマンドを使用して、Ubuntu の標準リポジトリから取得される各パッケージは、以下の4つのカテゴリに分類される。 1

  • Main
    • Ubuntu チームによってサポートされる、フリーソフトウェアを収容するコンポーネントで、 2,300 以上のパッケージを含む。
    • Ubuntu インストール時にデフォルトでインストールされるパッケージの大半はこれ。
  • Restricted
    • ドライバーなど、利便性の面でデフォルトでインストールされたほうが望ましいものの、プロプライエタリであるソフトウェアを含むコンポーネント。
  • Universe
    • Ubuntu コミュニティによって管理されている、 Linux 界の多くのオープンソースソフトウェアを収容するコンポーネントで、 23,000 以上のパッケージを含む。
  • Multiverse
    • フリーソフトの要件を満たさないような、特殊なライセンス要件をもつソフトウェアを収容するコンポーネント。
    • GPU 関連 (CUDA 等) や, VirtualBox などが含まれている。

これらのうち、Restricted と Multiverse リポジトリのパッケージについては、それぞれのソフトの提供元によってのみメンテナンスされ、Canonical によるサポートは行われない。

一方で、Main と Universe リポジトリのパッケージについては、セキュリティ修正の提供期間や、電話/オンラインチケットサポート範囲が、 Ubuntu Pro の有無やライセンスの種類ごとに以下のような内訳となっている。 2

Security patching Ubuntu LTS Ubuntu Pro (Infra-only) Ubuntu Pro
Over 2,300 packages in Ubuntu Main repository 5 years 10 years 10 years
Over 23,000 packages in Ubuntu Universe repository Best effort Best effort 10 years
Optional phone/ticket support No Yes Yes

5年のLTSの期間中、Main リポジトリのパッケージを主に使用する場合、(ライブパッチ等の他のUbuntu Proのサービスが不要であれば)無料の範囲内で十分だ。

Main リポジトリのパッケージを主に使用しながら、10年の延長サポートを望む場合は、"Ubuntu Pro (Infra-only)" を契約することをおすすめする。

また、Universe リポジトリのパッケージを積極的に活用したい場合は、"Ubuntu Pro" を契約しておくと、より安心だろう。

Ubuntu の Universe リポジトリのパッケージの更新基準

続きを読む

置換ができない/複数ある場合に sed の終了コード0以外にする

本記事は、 シェルスクリプト Advent Calendar 2021 の 4日目 の記事だ。
そして、 且つ docker Advent Calendar 2021 4日目 の記事でもある。

どちらのカレンダーもまだまだスッカスカなので、禁じ手で埋めにかかってしまった。


Docker 公式イメージ などをベースにして、カスタムしてイメージをビルドして使おうとした際、 なるべくなら /etc/apt/apt.conf.d/ 等のように、設定用のファイルを追加して、ツール側がいい感じにマージして利用してくれるのが望ましい。
しかし、 場合によってはやむを得ず、既存のファイルを sed コマンドなどで編集せざるを得ないこともあるだろう。

カスタムイメージの Dockerfile をビルドする際に、当初は意図通り書き換えられていても、イメージが更新された結果、イメージのリビルド時にファイルの書き換えが意図しない結果となってしまう場合がある。 1

通常、 sed コマンドは、置換が発生してもしなくても、 終了コード 0 で終了する。
このため、書き換えの成否にかかわらず、 docker build 時にエラーにならないため、コンテナ実行時に初めて置換が意図しない結果だったことに気づくことがある。

そこで、sed コマンドの書き換えで適切なパターンが見つからなかった場合に 0以外の終了コードを返し、ビルド時にエラーとする方法を考える。

続きを読む

sed の ブロック {} 内で i, r, e コマンドを使うと “unmatched `{‘” とエラーになる

本記事は、 シェルスクリプト Advent Calendar 2021 の 3日目 の記事だ。
3日目が終わりそうになっても誰も書きそうにないので、最近 sed コマンドで ブロック {} を使っていたら、 "unmatched `{" というエラーにハマったので、そのメモ。


target.txt:

foo
bar
foo
bar
foo

insert.txt:

***

上記のような、2つのファイルがあったとする。

target.txt ファイルに対して、 正規表現アドレスbar から始まる行を選択し、 その後ろに r コマンド insert.txt のファイルの中身を挿入する。

するとこんな結果になる。

$ sed -e '/^bar/rinsert.txt' target.txt
foo
bar
***
foo
bar
***
foo

では、アドレス指定の後ろにブロック {} を追加し、以下のように bar が2回以上ヒットしたらエラーコード出して終了するようにしてみる。

$ sed -e '/^bar/{rinsert.txt;x;/./Q129;g}' target.txt
sed: -e expression #1, char 0: unmatched `{'
$ echo $?
1

はい、別のエラーで失敗した。
ちゃんと {} の数はマッチしているのに……

続きを読む