Ubuntu Weekly Recipe

第516回 command-not-found再発見

この記事を読むのに必要な時間:およそ 3.5 分

オプション付きで実行する

command-not-foundにはいくつかのオプションがあります。⁠無効化する」と同じような方法で~/.bashrc上で関数を上書きすることで,任意のオプションを指定できます。

使えるオプションは次のとおりです。

  • --data-dir」⁠データディレクトリを/usr/share/command-not-foundに変更します。
  • --ignore-installed」⁠インストール済みかどうかのチェックを行いません。
  • --no-failure-msg」⁠候補が見つからなかったときは何も表示しません。

データディレクトリはパッケージ名とコマンド名のデータベースを格納しているディレクトリです。データベースはcommand-not-found-dataパッケージが提供します。独自のデータベースを使いたい場合などに使用します。

「インストール済みかどうかのチェック」は少し説明が必要かもしれません。たとえば/sbin/partedがインストール済みの環境でなおかつ環境変数PATH/sbinが含まれていない場合を考えます。bash的にはpartedは見つからない状態になるのですが,command-not-foundは環境変数PATHだけでなく「一般的なコマンドパス」も検索しているため/sbin/partedコマンドを見つけられます。これが「インストールされているが見つからないコマンド」です。

command-not-foundはこのようなコマンドを「インストール済み」として扱いそのフルパスを提示します。しかしながら,PATHで見つからない場合は存在しないものとしてパッケージを提案してほしい場合もあるかもしれません。--ignore-installedはそんな用途に適したオプションです。

候補が1つだったらインストールするか問い合わせる

候補が1つだった場合,対象のパッケージをインストールしてくれると,表示されるメッセージをコピー&ペーストする手間が省けます。環境変数COMMAND_NOT_FOUND_INSTALL_PROMPTに適当な値をセットしておくと,そのような動作になります。

$ export COMMAND_NOT_FOUND_INSTALL_PROMPT=y
$ sl
プログラム 'sl' はまだインストールされていません。 次のように入力することでインストールできます:
sudo apt install sl
インストールしますか? (N/y)

何も入力せずにエンターを押した時はインストールしないようになっていますので安心ですね。

特定のコマンドはデータベース問い合わせさせない

「よく打ち間違えるコマンド」ってありませんか?

「grep」「grpe」「git」「gti」になっていたり,⁠ls」のつもりが「rm」って打っていたり,⁠vi」って打つつもりが「emacs」って打ってしまったり……。

いわゆる「手グセ」に起因するものから,キーボードが原因だったり,睡眠不足が原因だったりと打ち間違える理由は様々です。また頻繁に打ち間違えるものに対して,毎回「まだインストールされていません」とか言われるとイラッときますよね。いや,自業自得なんですが。

~/.command-not-found.blacklist「よく打ち間違えるコマンド」をいくつか入れておくと,command-not-foundはそれを無視してくれます。

$ sl
プログラム 'sl' はまだインストールされていません。 次のように入力することでインストールできます:
sudo apt install sl
$ echo "sl" >> ~/.command-not-found.blacklist
$ sl
sl: コマンドが見つかりません
$ echo "grpe" >> ~/.command-not-found.blacklist
$ grpe
grpe: コマンドが見つかりません

データベースへの問い合わせをしなくなるだけで,command-not-foundコマンドは起動するので少ししか応答性はあがりませんが※4)⁠それでもそれなりに気持ちが楽になることでしょう。

※4
ストレージ性能の低いARMデバイスを使っていると,command-not-foundによるロスはけっこう大きく感じます。

Ubuntu 18.04 LTSでの変更点

このcommand-not-found,ここ数回のUbuntuリリースにおいてはデータベースファイルの更新しか行っていませんでした。つまりコードはほぼそのままでした。修正されたとしてもPython3への対応とか,apt-getからaptへの変更など,周囲の環境にあわせた微調整にとどまっていたのです。

しかしながらUbuntu 18.04 LTSの開発期間では,何がどうなったのか活発にコミットが行われます※5)⁠1リリース1コミットぐらいの頻度だったのが,ここ半年で60コミット以上,当社比60倍です!

※5
ちなみにリビジョン管理システムは今もBazaarです。
  • snapパッケージのコマンドのサポート
  • snapパッケージとDebianパッケージの両方の候補があればバージョンも表示
  • データベースをGNU dbmからSQLiteへ移行
  • リポジトリ上のコマンドメタデータからデータベースを構築(未実装?)
  • pyflakes/autopkgtestなどによるコードチェックやテストの実装
  • 数千文字渡したときにシステムが固まる問題の修正LP: #1605732
  • より読みやすくなるよう表示内容の調整
  • Python2のサポート終了

おそらくユーザー側が最も恩恵を受けるのが,snapの対応とSQLiteへの移行でしょう。特にSQLiteになることで,低スペック環境下でのcommand-not-foundの「待ち」がだいぶ減ったように感じます。

コマンドメタデータからのデータベース構築は,sudo apt update時をトリガーとしてリポジトリ上のデータからデータベースを再構築する仕組みです。ただしまだリポジトリ側が対応していないようにも見えますので,おそらく将来を見据えた実装なのでしょう。

このようにcommand-not-foundは18.04で大きく変わる予定です。これを機に,今一度手元のツールを見なおしてみてはいかがでしょうか。

著者プロフィール

柴田充也(しばたみつや)

Ubuntu Japanese Team Member株式会社 創夢所属。数年前にLaunchpad上でStellariumの翻訳をしたことがきっかけで,Ubuntuの翻訳にも関わるようになりました。