如何在bash shell中实现命令建议?

时间:2016-03-01 00:50:22

标签: bash shell search-suggestion autocorrect

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

我目前实施了一个简单的“你的意思是......”'对于简单的英语单词,其工作原理如下:

  • 如果用户输入了Kack',请检查QWERTY键盘上单词中每个字母表周围的字母,然后逐个替换它们。 (例如,在这里它们将是J,L,M,I,O用于' K&#39 ;; Q,W,S,Z,X用于' a'等等)
  • 最有可能返回单词(如果是这种情况,用户也自己输入单词)作为基于文本语料库培训的最可能单词。

如何在linux命令行中实现代码建议?

2 个答案:

答案 0 :(得分:5)

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 -- "$1";
        return $?;
    else
        if [ -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" 1>&2;
            return 127;
        fi;
    fi
}

/usr/lib/command-not-found存在,可执行,是一个Python脚本。)

答案 1 :(得分:1)

来自Bash手册页:

  

命令执行

     

[...]

     

如果名称既不是shell函数也不是内置函数,并且不包含斜杠,则bash会在PATH的每个元素中搜索包含该名称的可执行文件的目录。 Bash使用哈希表来记住可执行文件的完整路径名(请参阅下面的 SHELL BUILTIN COMMANDS 下的hash)。仅当在哈希表中找不到该命令时,才会执行PATH中目录的完整搜索。如果搜索不成功,shell将搜索名为command_not_found_handle的已定义shell函数。如果该函数存在,则使用原始命令和原始命令的参数作为其参数调用它,函数的退出状态将成为shell的退出状态。如果未定义该函数,则shell将输出错误消息并返回退出状态127。

让我们试一试:

$ foobar
bash: foobar: command not found
$ function command_not_found_handle { echo "I'm so sorry, what is '$1'?"; }
$ 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 "$1"
    else
        echo "$1: Command not found" >&2
        return 127
    fi
}

这样,如果稍后安装或删除command-not-found软件包,则不必更改配置文件。

我不知道Ubuntu的程序是如何实现的,但通常情况下,这样的工具会列出所有已知命令并找到最相似的命令。然后它可能会检查是否安装了该程序,如果没有,请检查提供它的程序包并建议安装它。

通常通过计算两个字符串之间的edit distance来搜索“类似文本”。考虑到当前的键盘布局,考虑到给定字母的错误输入的可能性是一个非常聪明的补充。