2016-03-01 61 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