archlinux 提示未安装命令(本地搜索)

sh/bash/dash/ksh/zsh等Shell脚本
回复
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

archlinux 提示未安装命令(本地搜索)

#1

帖子 xiooli » 2009-07-07 21:35

RT:
http://joolix.com/2009/07/archlinux-com ... nd_handle/
用ubuntu的时候,如果你在命令行里输入一个未安装的命令,bash会给出很人性化的提示,让你先安装xxx软件包,比如:

程序 ‘xxx’ 尚未安装。 您可以通过输入以下命令安装:
sudo apt-get install xxx

通过e-file,再经过一点设置,在gentoo里面也可以达到类似的效果(参考骨头的文章:gentoo也可以提示未安装的命令:http://li2z.cn/2009/07/02/command_not_found_handle/

这些都是通过重定义bash的command_not_found_handle函数来实现的,archlinux上也有一些方案,比如通过 pacman -Si/pacman -Ss 来搜索的,前者只能找软件包而不能提示具体的命令,后者要通过网络实时查找。还有通过一个叫做pac-file(类似gentoo中的e-file)来找,这个命令可以从效果上完美实现这个功能,但是如果程序列表比较大或者机器慢的话,那么查找起来可能就是硬盘飞奔,CPU狂飙,而且过了一段时间后还得自己手动更新软件列表。这几种方案均不是很完美,于是俺只好自己动手,丰衣足食了,思路如下:

1) 在用pacman -Sy的时候自动更新pac-file的软件列表
2) 将所有的可执行命令项放到另一个文件里面,到时候去这里查找(因为pac-file的列表包含了软件包的所有文件项,故查找起来很慢,而我们要提示的是命令,也就是可执行文件,所以可以缩小搜索范围)

好,开工,代码如下,只需将其写到~/.bashrc里面再运行一下 . ~/.bashrc 就可以了:

代码: 全选

#pacman 简写,pacman更新同时更新pac-file并产生只含有可执行文件项的软件包列表。
pm () {
 
	if [ "`which powerpill 2>/dev/null`" ]; then
		sudo powerpill $@
	else
		sudo pacman $@
	fi
 
	arg="`sed 's/ //g;s/-//g' <<< $@`"
	[ "$arg" -a "$arg" != "${arg//Sy}" ] && {
	sudo pac-file -S
	[ -d $HOME/.Share/ ] || mkdir -p $HOME/.Share/
	pac-file bin/[^\/]+$ > $HOME/.Share/cmd.list && echo "cmd.list 已更新!"
	}
}
 
#命令未找到时的处理,从cmd.list里面去查找软件包
command_not_found_handle() {
	echo "-bash: $1: 命令未找到"
	if [ "`grep bin/$1$ $HOME/.Share/cmd.list`" ]; then
		echo "下列软件包含有命令 $1 :"
		grep bin/$1$ $HOME/.Share/cmd.list
	else
		echo "未搜索到含有命令 $1 的软件包 :("
	fi
}
现在查找速度终于快了哈,而且pacman更新同时就更新了pac-file的列表,再不用担心软件包的版本过期了^^
看看效果吧:
kmail3.png
头像
bones7456
帖子: 8495
注册时间: 2006-04-12 20:05
来自: 杭州
联系:

Re: archlinux 提示未安装命令(本地搜索)

#2

帖子 bones7456 » 2009-07-07 21:36

支持~ :em11
关注我的blog: ε==3
头像
Jarson
帖子: 2371
注册时间: 2008-07-21 9:44
来自: 深圳
联系:

Re: archlinux 提示未安装命令(本地搜索)

#3

帖子 Jarson » 2009-07-07 21:42

mark~~
头像
chenfengyuan的马甲
帖子: 25
注册时间: 2009-07-06 7:57

Re: archlinux 提示未安装命令(本地搜索)

#4

帖子 chenfengyuan的马甲 » 2009-07-08 8:43

mark
头像
c\nc
帖子: 231
注册时间: 2007-12-25 12:51

Re: archlinux 提示未安装命令(本地搜索)

#5

帖子 c\nc » 2009-07-08 14:36

是不是在最后面加上一行比较好:

代码: 全选

(exit 127)
毕竟这个命令没找到,用在脚本里就出问题了吧?
头像
adagio
论坛版主
帖子: 22110
注册时间: 2008-02-17 23:47
来自: 美丽富饶的那啥星球

Re: archlinux 提示未安装命令(本地搜索)

#6

帖子 adagio » 2009-07-08 15:17

收藏 :em11
明天就换大三八!
——8核CPU、8G内存、8T硬盘……
8卡交火,80寸大屏放8个……
IPv8的光纤要8条……

---------------------------------------------------------------------------------
[图片版]新手当自强(续)FAQ
[新手进阶]挂载、fstab、调整linux分区
[图片版]E17桌面环境配置手把手
liqiangjack
帖子: 4
注册时间: 2009-07-02 10:21

Re: archlinux 提示未安装命令(本地搜索)

#7

帖子 liqiangjack » 2009-07-08 17:10

:em11 :em11 很好很强大
头像
xiooli
帖子: 6956
注册时间: 2007-11-19 21:51
来自: 成都
联系:

Re: archlinux 提示未安装命令(本地搜索)

#8

帖子 xiooli » 2009-07-08 17:31

c\nc 写了:是不是在最后面加上一行比较好:

代码: 全选

(exit 127)
毕竟这个命令没找到,用在脚本里就出问题了吧?
找不到就知道去安装嘛 :em02
头像
roylez
帖子: 1928
注册时间: 2005-10-04 10:59
来自: 上海

Re: archlinux 提示未安装命令(本地搜索)

#9

帖子 roylez » 2009-07-09 9:35

我的:

代码: 全选

command_not_found_handler () {
        echo "Man, you really need some coffee. \nA clear-headed one would not type things like \"$1\"." | cowsay -f small -W 50
        echo
        pac-file /$1$ | awk '{split($1,a,"/");print a[1] "/\033[31m" a[2] "\033[m\t\t/" $2}'
        return 0
}
图片
弄个dropbox空间来备份文件或者做私人代码服务器
配置:[url]git://github.com/roylez/dotfiles.git[/url]
主页:http://roylez.heroku.com
各种稀奇玩意儿:http://dooloo.info
scoky
帖子: 99
注册时间: 2007-07-21 9:12

Re: archlinux 提示未安装命令(本地搜索)

#10

帖子 scoky » 2009-07-09 11:23

这个pac-file 是在哪里找的?源里的是pacfile?
头像
HuntXu
帖子: 5776
注册时间: 2007-09-29 3:09

Re: archlinux 提示未安装命令(本地搜索)

#11

帖子 HuntXu » 2009-07-09 11:29

scoky 写了:这个pac-file 是在哪里找的?源里的是pacfile?
就是这个
HUNT Unfortunately No Talent...
scoky
帖子: 99
注册时间: 2007-07-21 9:12

Re: archlinux 提示未安装命令(本地搜索)

#12

帖子 scoky » 2009-07-09 11:36

里面的命令不再是pac-file了,是pacfile。。。。。
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: archlinux 提示未安装命令(本地搜索)

#13

帖子 tusooa » 2009-07-23 19:19

代码: 全选

23/07/2009 19:11:55                                      
tusooa (~)                                               
>> cat /etc/bash.bashrc                                  
# System-wide .bashrc file for interactive bash(1) shells.

# To enable the settings / commands in this file for login shells as well,
# this file has to be sourced in /etc/profile.                            

# If not running interactively, don't do anything
[ -z "$PS1" ] && return                          

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.                    
shopt -s checkwinsize                                        

# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then               
    debian_chroot=$(cat /etc/debian_chroot)                                 
fi                                                                          

# set a fancy prompt (non-color, overwrite the one in /etc/profile)
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '                

# Commented out, don't overwrite xterm -T "title" -n "icontitle" by default.
# If this is an xterm set the title to user@host:dir                        
#case "$TERM" in                                                            
#xterm*|rxvt*)                                                              
#    PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'     
#    ;;                                                                     
#*)                                                                         
#    ;;                                                                     
#esac                                                                       

# enable bash completion in interactive shells
#if [ -f /etc/bash_completion ]; then         
#    . /etc/bash_completion                   
#fi                                           

# sudo hint
if [ ! -e $HOME/.sudo_as_admin_successful ]; then
    case " $(groups) " in *\ admin\ *)           
    if [ -x /usr/bin/sudo ]; then                
        cat <<-EOF                               
        To run a command as administrator (user "root"), use "sudo <command>".
        See "man sudo_root" for details.                                      

        EOF
    fi     
    esac   
fi         

# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found ]; then             
        function command_not_found_handle {            
                # check because c-n-f could've been removed in the meantime
                if [ -x /usr/lib/command-not-found ]; then                 
                   /usr/bin/python /usr/lib/command-not-found -- $1        
                   return $?                                               
                else                                                       
                   return 127                                              
                fi                                                         
        }                                                                  
fi
23/07/2009 19:12:07
tusooa (~)
>> cat /usr/lib/command-not-found
#!/usr/bin/python
# (c) Zygmunt Krynicki 2005, 2006, 2007, 2008
# Licensed under GPL, see COPYING for the whole text

__version__ = "0.2.21"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/+source/command-not-found"

import CommandNotFound
import sys
from CommandNotFound.util import crash_guard, gettext_wrapper as _
from CommandNotFound import CommandNotFound
from optparse import OptionParser

def main():
    parser = OptionParser(version = __version__, usage=_("%prog [options] <command-name>"))
    parser.add_option('-d', '--data-dir', action='store',
                      default="/usr/share/command-not-found",
                      help=_("use this path to locate data fields"))
    parser.add_option('--ignore-installed', '--ignore-installed',
                      action='store_true',  default=False,
                      help=_("ignore local binaries and display the available packages"))
    (options, args) = parser.parse_args()
    if len(args) == 1:
        CommandNotFound(options.data_dir).advise(args[0], options.ignore_installed)

if __name__ == "__main__":
    crash_guard(main, BUG_REPORT_URL, __version__)
23/07/2009 19:13:55
tusooa (~)
>>
c\nc 写了:是不是在最后面加上一行比较好:

代码: 全选

(exit 127)
毕竟这个命令没找到,用在脚本里就出问题了吧?
Ubuntu的是exit $?

代码: 全选

] ls -ld //
回复