Bash的command_not_found_handle

May 5, 2013

在Ubuntu的bash里,当你输入一个不存在的命令时,bash不会简单地提示command not found,反而会提示一些可能的命令,很方便。后来换到Fedora和Arch,就没用过这功能了。

在我bash里有一些这样的函数:

function zathura () {
    if [[ -z $(type -P zathura) ]]; then
	a-setup zathura
    fi
    $(type -P zathura) -d /tmp/ -p /tmp/tmproot/lib/zathura --fork $@
}

在shell里执行zathura的时候就执行这个函数,这个函数会在PATHzathura,如果找到就执行,没找到就先用a-setup安装再执行。类似的函数还有另外3个。

这让我想起了Ubuntu里的bash,一查发现bash在没找到命令的时候会尝试执行command_not_found_handle这个函数,所以我就写了一个:

function command_not_found_handle() {
    target=$1
    shift 1
    args="$@"

    read -p "bash: setup $target ? (y/n)" -n 1 -r
    echo ""

    if [[ $REPLY =~ ^[Yy]$ ]]; then
	a-setup "^$target"[.-]
	if [[ $? == 0 ]]; then
	    $target $args
	fi
    else
	echo bash: $target: command not found
	return 1
    fi
}

我还加了个选项,可以选择是否安装。

当然,要完整实现上面的zathura函数,我们还要加上一些选项,这里用alias实现:

alias zathura='zathura -d /tmp/ -p /tmp/tmproot/lib/zathura --fork'

或者在函数里用command实现:

function zathura() {
    command zathura -d /tmp/ -p /tmp/tmproot/lib/zathura --fork "$@"
}

感觉比以前方便多了。