Ubuntu で「コマンドが見つかりません」ハンドラにフックする

Ubuntu で「コマンドが見つかりません」ハンドラにフックする

コマンドが見つからない場合のハンドラにフックしたい

wim@SDFA100461C:~$ thing
No command 'thing' found, did you mean:
 Command 'tping' from package 'lam-runtime' (universe)
 Command 'thin' from package 'thin' (universe)
thing: command not found

この動作を独自のスクリプトで上書きしたいと思います。

具体的には、 の出力にコマンドが存在するかどうかを確認しlsvirtualenv -b、存在する場合はその仮想環境をアクティブ化します。

どこからハッキングを始めればよいでしょうか?

答え1

の場合bash、その動作はシェル関数によって制御されますcommand_not_found_handle( man bash「コマンド実行」の「 」を参照)。

その関数によってどのような動作が定義されているかを確認するには、次のコマンドを発行します。

declare -p -f command_not_found_handle

関数を再定義することで、使用するプログラムを変更できますcommand_not_found_handle

Ubuntu 14.04 LTS では、デフォルトの動作は次のように直接定義されているようです/etc/bash.bashrc:

# 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

答え2

一般的に

Linuxジャーナルかなり良い記事があります:

bash のマニュアルページより:

... PATH 内のディレクトリの完全検索は、ハッシュ テーブルでコマンドが見つからない場合にのみ実行されます。検索が失敗した場合、シェルは command_not_found_handle という名前の定義済みシェル関数を検索します。その関数が存在する場合、元のコマンドと元のコマンドの引数を引数としてその関数が呼び出され、関数の終了ステータスがシェルの終了ステータスになります。その関数が定義されていない場合、シェルはエラー メッセージを出力し、終了ステータス 127 を返します。

そして

/etc で grep を実行すると、どこで問題が発生しているかがわかりました。関数自体は /etc/bash_command_not_found にあり、その関数は (存在する場合) /etc/bash.bashrc 経由で bash セッションに含まれます。

ウブントゥ 14.04

経験的証拠によれば、Ubuntu 14.04のインストールでは、ファイル/etc/bash_command_not_foundは存在しないが、正しいファイルはpythonスクリプトであり、次の場所にある。/usr/lib/コマンドが見つかりません

関連情報