Ubuntuには
command-not-foundの仕組み
UbuntuでCLIで操作している時、
プログラム 'sl' はまだインストールされていません。 次のように入力することでインストールできます: sudo apt install sl
これは
command-not-foundはUbuntu 6.
仕組みはすごく単純です。Bashには検索パスにコマンドが見つからない場合、command_
関数を呼び出すという仕組みが存在します。Ubuntuのbashパッケージが提供する/etc/
には最初から、command-not-found
がインストール済みならcommand_
を定義するスクリプトが組み込まれていますので、
# if the command-not-found package is installed, use it if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then function command_not_found_handle { # check because c-n-f could've been removed in the meantime if [ -x /usr/lib/command-not-found ]; then /usr/lib/command-not-found -- "$1" return $? elif [ -x /usr/share/command-not-found/command-not-found ]; then /usr/share/command-not-found/command-not-found -- "$1" return $? else printf "%s: command not found\n" "$1" >&2 return 127 fi } fi
command-not-foundの実体は/usr/
です。ここにコマンド引数の最初の文字列
PATH
にはないもののインストール済みかをチェックする- apt/
aptitudeがインストールされていない場合は、 ただ 「見つかりません」 のエラーのみを表示する - ブラックリスト
(後述) に見つかったら、 ただ 「見つかりません」 のエラーのみを表示する - パス名から該当するパッケージを検索する
- パッケージが複数見つかったらパッケージリストとインストール方法を表示する
- 該当するパッケージが1つのときはインストール方法
( sudo apt PACKAGE
)を提示する - 該当パッケージのコンポーネント
(mainやuniverse) が無効化されていたら有効化するように伝える - パッケージが見つからずなおかつコマンドが3文字以上なら単なるスペルミスの可能性を考慮して
「もしかして」 を表示する
つまり
プログラム 'sl' はまだインストールされていません。 'sl' を利用するために、コンピュータの管理者に 'sl' をインストールすることを相談してください
動作をカスタマイズする
command-not-foundは初心者にとって便利な機能ですが、
command-not-foundを無効化する
無効化する一番手っ取り早い方法は、~/.bashrc
」
# disable command-not-found function command_not_found_handle { printf "%s: command not found\n" "$1" >&2 return 127 }
要するに関数の定義を上書きしているだけですね。
オプション付きで実行する
command-not-foundにはいくつかのオプションがあります。~/.bashrc
」
使えるオプションは次のとおりです。
- 「
--data-dir
」:データディレクトリを「 /usr/
」share/ command-not-found に変更します。 - 「
--ignore-installed
」:インストール済みかどうかのチェックを行いません。 - 「
--no-failure-msg
」:候補が見つからなかったときは何も表示しません。
データディレクトリはパッケージ名とコマンド名のデータベースを格納しているディレクトリです。データベースはcommand-not-found-dataパッケージが提供します。独自のデータベースを使いたい場合などに使用します。
「インストール済みかどうかのチェック」/sbin/
」PATH
に/sbin
が含まれていない場合を考えます。bash的にはparted
」PATH
だけでなく/sbin/
コマンドを見つけられます。これが
command-not-foundはこのようなコマンドをPATH
で見つからない場合は存在しないものとしてパッケージを提案してほしい場合もあるかもしれません。--ignore-installed
」
候補が1つだったらインストールするか問い合わせる
候補が1つだった場合、COMMAND_
に適当な値をセットしておくと、
$ export COMMAND_NOT_FOUND_INSTALL_PROMPT=y $ sl プログラム 'sl' はまだインストールされていません。 次のように入力することでインストールできます: sudo apt install sl インストールしますか? (N/y)
何も入力せずにエンターを押した時はインストールしないようになっていますので安心ですね。
特定のコマンドはデータベース問い合わせさせない
「よく打ち間違えるコマンド」
「grep」
いわゆる
「~/.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: コマンドが見つかりません
データベースへの問い合わせをしなくなるだけで、
Ubuntu 18.04 LTSでの変更点
このcommand-not-found、
しかしながらUbuntu 18.
- snapパッケージのコマンドのサポート
- snapパッケージとDebianパッケージの両方の候補があればバージョンも表示
- データベースをGNU dbmからSQLiteへ移行
- リポジトリ上のコマンドメタデータからデータベースを構築
(未実装?) - pyflakes/
autopkgtestなどによるコードチェックやテストの実装 - 数千文字渡したときにシステムが固まる問題の修正
(LP: #1605732) - より読みやすくなるよう表示内容の調整
- Python2のサポート終了
おそらくユーザー側が最も恩恵を受けるのが、
コマンドメタデータからのデータベース構築は、sudo apt update
」
このようにcommand-not-foundは18.