2016-03-01 60 views
2
[email protected]:~$ 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 

我目前实现了一个简单的'你的意思是...?'对于其工作原理如下简单的英语单词:在bash shell中如何实现命令建议?

  • 如果用户输入“Kack”,检查周围的每一个字母的字母在单词在QWERTY键盘上,并通过一个代替它们之一。 (例如,在这里它们将是J,L,M,I,O代表'K'; Q,W,S,Z,X代表'a'等等)
  • 返回单词的概率最高如果是这种情况,也输入单词本身)作为基于对文本语料库的训练的最可能的单词。

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

回答

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脚本。)

+0

谢谢!你怎么知道这件事的?我的意思是用更一般的方式说,没有SO,我怎么才能从CLI中发现什么函数? – Ketcomp

+1

@Kcompcomp:阅读“男人bash”。 (位于'COMMAND EXECUTION'部分的第三段。) – rici

1

从猛砸男子页:

命令执行

[...]

如果该名称既不是shell函数也不是内建函数,并且不包含斜杠,bash会搜索PATH的每个元素以获取包含该名称的可执行文件的目录。 Bash使用哈希表来记住可执行文件的完整路径名(请参阅hash下的SHELL BUILTIN命令)。仅当在哈希表中未找到该命令时,才会执行PATH中目录的完整搜索。如果搜索不成功,shell会搜索名为command_not_found_handle的定义的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包被改变。

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

搜索“相似文本”通常是通过计算两个字符串之间的edit distance来完成的。考虑到给定的字母在给定当前键盘布局的情况下可能会被误认为是一个非常聪明的添加。

+0

在rici的回答之后,我试图使用grep在手册页中找到这些相关数据。但后来你发布了这个;)+1为了更好地说明逻辑,对函数进行在线重定义! – Ketcomp

+2

@Ketcomp:在'man bash'(或者'man'任何东西)中,你可以通过输入'/'后面跟着你想要搜索的字符串进行搜索,假设你使用'less'作为你的寻呼机。 'h'会给你一个可能的'less'命令的概要。你会发现比'grep'更容易。 – rici