我喜欢使用 Ubuntu 的一件事是,当输入不存在的命令时,它会建议类似的命令(以及具有类似命令的软件包)。
我在 Manjaro 上,当我输错命令时,比如msg
不是mesg
,它只返回bash: msg: command not found
。我想Did you mean [similar command]
在 Ubuntu 上留言。
有没有办法在 Arch Linux 上获得类似命令的此类建议?
答案1
您可以安装pacman -S pkgfile
、执行sudo pkgfile --update
并将其添加到您的~/.bashrc
:
source /usr/share/doc/pkgfile/command-not-found.bash
来自拱门维基:
然后尝试运行不可用的命令将显示以下信息:
$ abiword
abiword 可以在以下软件包中找到: extra/abiword 3.0.1-2 /usr/bin/abiword
但这不会搜索类似的命令。
还有AUR未找到命令包它承诺更多,但目前被标记为过时。您也许可以在 github 上联系作者(https://github.com/metti/command-not-found)。
答案2
由于我现在没有找到任何可用的软件包来为 Arch Linux 实现此功能,因此我尝试编写一个相同的解决方案。
对于这个解决方案,我们利用PROMPT_COMMAND
变量 和compgen
。
脚步
- 创建一个包含以下内容的 python 文件。我将其命名为
temp.py
.
#!/usr/bin/env python
import sys
def similar_words(word):
"""
return a set with spelling1 distance alternative spellings
based on http://norvig.com/spell-correct.html
"""
alphabet = 'abcdefghijklmnopqrstuvwxyz-_0123456789'
s = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [a + b[1:] for a, b in s if b]
transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b) > 1]
replaces = [a + c + b[1:] for a, b in s for c in alphabet if b]
inserts = [a + c + b for a, b in s for c in alphabet]
return set(deletes + transposes + replaces + inserts)
def bash_command(cmd):
import subprocess
sp = subprocess.Popen(['/bin/bash', '-c', cmd], stdout=subprocess.PIPE)
return [s.decode('utf-8').strip() for s in sp.stdout.readlines()]
def main():
word = sys.argv[1]
command_list = bash_command('compgen -ck')
result = list(set(similar_words(word)).intersection(set(command_list)))
if len(result) > 0:
wrong_command_str = "Did you mean?"
indent = len(wrong_command_str)//2
print("Did you mean?")
for cmd in result:
print(indent*" ",cmd)
if __name__ == '__main__':
main()
- 将 python 脚本附加到您的
$PROMPT_COMMAND
变量中。
export PROMPT_COMMAND='if [ $? -gt 0 ]; then python test.py $(fc -nl | tail -n 1 | awk "{print $1}"); fi;'$PROMPT_COMMAND
- 检查之前的命令是否失败。
$? -gt 0
- 如果失败,获取命令的名称。
fc -nl | tail -n 1 | awk "{print $1}"
- 使用 python 脚本查找相近的匹配项。
python test.py <command-name>