bashshell中的命令建议是如何实现的?
How is the command suggestion implemented in the bash shell?
gk@Jarvis:~$ sudi
No command 'sudi' found, did you mean:
Command 'sudo' from package 'sudo-ldap' (universe)
Command 'sudo' from package 'sudo' (main)
sudi: command not found
我目前已经为简单的英语单词实现了一个简单的 'Did you mean..?',其工作原理如下:
- 如果用户输入'Kack',检查QWERTY键盘上单词中每个字母周围的字母,并一一替换。 (例如,'K' 为 J、L、M、I、O;'a' 为 Q、W、S、Z、X 等等)
- Return 最有可能的词(如果是这种情况,用户也输入词本身)作为基于文本语料库训练的最有可能的词。
如何在 linux 命令行中实现代码建议?
bash
没有实现建议逻辑;它位于定义为 bash 初始化文件的一部分的函数中,并且由您的分发版(Ubuntu/Debian 猜测)放在那里。
bash
提供了实现这样一个函数的机制:当它试图执行一个命令,但没有找到该命令时,它会调用函数 command_not_found_handle
,如果它被定义的话。
在我的机器上(Ubuntu 变体),该函数定义如下:
$ type command_not_found_handle
command_not_found_handle is a function
command_not_found_handle ()
{
if [ -x /usr/lib/command-not-found ]; then
/usr/lib/command-not-found -- "";
return $?;
else
if [ -x /usr/share/command-not-found/command-not-found ]; then
/usr/share/command-not-found/command-not-found -- "";
return $?;
else
printf "%s: command not found\n" "" 1>&2;
return 127;
fi;
fi
}
(并且 /usr/lib/command-not-found
存在,可执行,并且是一个 Python 脚本。)
来自 Bash 手册页:
COMMAND EXECUTION
[…]
If the name is neither a shell function nor a builtin, and contains no slashes, bash searches each element of the PATH
for a directory containing an executable file by that name. Bash uses a hash table to remember the full pathnames of executable files (see hash
under SHELL BUILTIN COMMANDS below). A full search of the directories in PATH
is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell searches for a defined shell function named command_not_found_handle
. If that function exists, it is invoked with the original command and the original command's arguments as its arguments, and the function's exit status becomes the exit status of the shell. If that function is not defined, the shell prints an error message and returns an exit status of 127.
让我们试试看:
$ foobar
bash: foobar: command not found
$ function command_not_found_handle { echo "I'm so sorry, what is ''?"; }
$ foobar
I'm so sorry, what is 'foobar'?
您的 shell 初始化代码可能会安装更有用的 command_not_found_handle
。您通常会在 /etc/bash.bashrc
中的系统范围配置或由它获取的文件中找到此类代码。您的发行版可能会在那里安装一个处理程序来调用一个外部程序,该程序向发行版的包管理器查询命令或“类似”命令。对于您的 Ubuntu,这将在 command-not-found
package.
中实现
发行版提供的默认配置文件通常非常通用,因此该函数可能会检查是否安装了 command-not-found
二进制文件,如果安装了,则调用它或以其他方式打印一条简单的错误消息。
function command_not_found_handle {
if [ -x /usr/bin/command-not-found ]
then
/usr/bin/command-not-found ""
else
echo ": Command not found" >&2
return 127
fi
}
这样,如果稍后再次安装或删除 command-not-found
包,则不必更改配置文件。
我不知道 Ubuntu 的程序是如何实现的,但通常,这样的工具会列出所有已知命令并找到最相似的命令。然后它可能会检查是否安装了该程序,如果没有,检查提供它的软件包并建议安装它。
搜索“相似文本”通常是通过计算两个字符串之间的 edit distance 来完成的。考虑到给定字母输入错误的可能性,考虑到当前的键盘布局,将是一个非常明智的补充。
gk@Jarvis:~$ sudi
No command 'sudi' found, did you mean:
Command 'sudo' from package 'sudo-ldap' (universe)
Command 'sudo' from package 'sudo' (main)
sudi: command not found
我目前已经为简单的英语单词实现了一个简单的 'Did you mean..?',其工作原理如下:
- 如果用户输入'Kack',检查QWERTY键盘上单词中每个字母周围的字母,并一一替换。 (例如,'K' 为 J、L、M、I、O;'a' 为 Q、W、S、Z、X 等等)
- Return 最有可能的词(如果是这种情况,用户也输入词本身)作为基于文本语料库训练的最有可能的词。
如何在 linux 命令行中实现代码建议?
bash
没有实现建议逻辑;它位于定义为 bash 初始化文件的一部分的函数中,并且由您的分发版(Ubuntu/Debian 猜测)放在那里。
bash
提供了实现这样一个函数的机制:当它试图执行一个命令,但没有找到该命令时,它会调用函数 command_not_found_handle
,如果它被定义的话。
在我的机器上(Ubuntu 变体),该函数定义如下:
$ type command_not_found_handle
command_not_found_handle is a function
command_not_found_handle ()
{
if [ -x /usr/lib/command-not-found ]; then
/usr/lib/command-not-found -- "";
return $?;
else
if [ -x /usr/share/command-not-found/command-not-found ]; then
/usr/share/command-not-found/command-not-found -- "";
return $?;
else
printf "%s: command not found\n" "" 1>&2;
return 127;
fi;
fi
}
(并且 /usr/lib/command-not-found
存在,可执行,并且是一个 Python 脚本。)
来自 Bash 手册页:
COMMAND EXECUTION
[…]
If the name is neither a shell function nor a builtin, and contains no slashes, bash searches each element of the
PATH
for a directory containing an executable file by that name. Bash uses a hash table to remember the full pathnames of executable files (seehash
under SHELL BUILTIN COMMANDS below). A full search of the directories inPATH
is performed only if the command is not found in the hash table. If the search is unsuccessful, the shell searches for a defined shell function namedcommand_not_found_handle
. If that function exists, it is invoked with the original command and the original command's arguments as its arguments, and the function's exit status becomes the exit status of the shell. If that function is not defined, the shell prints an error message and returns an exit status of 127.
让我们试试看:
$ foobar bash: foobar: command not found $ function command_not_found_handle { echo "I'm so sorry, what is ''?"; } $ foobar I'm so sorry, what is 'foobar'?
您的 shell 初始化代码可能会安装更有用的 command_not_found_handle
。您通常会在 /etc/bash.bashrc
中的系统范围配置或由它获取的文件中找到此类代码。您的发行版可能会在那里安装一个处理程序来调用一个外部程序,该程序向发行版的包管理器查询命令或“类似”命令。对于您的 Ubuntu,这将在 command-not-found
package.
发行版提供的默认配置文件通常非常通用,因此该函数可能会检查是否安装了 command-not-found
二进制文件,如果安装了,则调用它或以其他方式打印一条简单的错误消息。
function command_not_found_handle {
if [ -x /usr/bin/command-not-found ]
then
/usr/bin/command-not-found ""
else
echo ": Command not found" >&2
return 127
fi
}
这样,如果稍后再次安装或删除 command-not-found
包,则不必更改配置文件。
我不知道 Ubuntu 的程序是如何实现的,但通常,这样的工具会列出所有已知命令并找到最相似的命令。然后它可能会检查是否安装了该程序,如果没有,检查提供它的软件包并建议安装它。
搜索“相似文本”通常是通过计算两个字符串之间的 edit distance 来完成的。考虑到给定字母输入错误的可能性,考虑到当前的键盘布局,将是一个非常明智的补充。