2012-07-11 49 views
6

说我有:生成警告时,在bash命令执行时,在路的多个可执行文件

>which -a foo 
/bin/foo 
/usr/bin/foo 

我想是这样的:

>foo 
Warning: multiple foo in PATH 
... foo gets executed ... 

此功能会真的今天很多时间救了我。 我应该猜到这种情况在早些时候发生,但问题并不清楚 在开始时对我而言,我开始朝相反的方向挖掘。

回答

6

那么,你可以这样做,但这并不像你想像的那么容易。

首先,您需要创建一个函数来检查PATH中的所有目录,并查看您尝试运行的命令。 然后,您需要将此函数绑定到当前shell的DEBUG陷阱。

我写了一个小脚本,它是:

$ cat /tmp/1.sh 

check_command() 
{ 
    n=0 
    DIRS="" 
    for i in $(echo $PATH| tr : " ") 
    do 
     if [ -x "$i/$1" ] 
     then 
      n=$[n+1] 
      DIRS="$DIRS $i" 
     fi 
    done 
    if [ "$n" -gt 1 ] 
    then 
     echo "Warning: there are multiple commands in different PATH directories: "$DIRS 
    fi 
} 

preexec() { 
    check_command $1 
} 
preexec_invoke_exec() { 
    [ -n "$COMP_LINE" ] && return # do nothing if completing 
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`; 
    preexec "$this_command" 
} 
trap 'preexec_invoke_exec' DEBUG 

使用示例:

$ . /tmp/1.sh 
$ sudo cp /bin/date /usr/bin/test_it 
$ sudo cp /bin/date /bin/test_it 
$ test_it 
Warning: there are multiple commands in different PATH directories: /usr/bin /bin 
Wed Jul 11 15:14:43 CEST 2012 
$ 
+2

而不是迭代'$ PATH',你可以使用'type -pa“$ 1”'。你也许可以使用'$ BASH_COMMAND'而不是解析'history'。 'preexec'函数必须在另一个上下文中起作用,但在这里是无关紧要的。 – 2012-07-11 14:29:10

+0

哦,我想我会通过电子邮件通知问题的答案。 **谢谢。**我想简短的回答是“使用DEBUG陷阱”),因为其他的东西是更明显的bash mashinery。在这方面你的回答和@lynxlynxlynx都是很好的答案。尽管如此,我还是赞成你的回答,没有其他原因。 – nshy 2012-07-17 09:20:43

2

这是可能的,虽然有点技巧一般化。看到我的回答https://unix.stackexchange.com/q/42579/20437historyPROMPT_COMMAND魔法。你的checkSanity函数看起来是这样的:

checkSanity() { 
    cmd="${1%% *}" # strip everything but the first word 
    candidates=$(which -a $cmd | wc -l) 
    if ((candidates > 1)); then 
    echo "Warning: multiple $cmd in PATH" 
    fi 
} 

但是,这将在命令完成后打印警告,而不是在开始时。使用DEBUG陷阱来获得想要的结果:

trap 'checkSanity "$BASH_COMMAND"' DEBUG 
+1

据我可以理解,PROMPT_COMMAND不会在这里帮助;它在你进入命令行之前执行,而不是在之后执行。 – 2012-07-11 13:10:39

+0

它可以工作,但在命令结束后您会收到警告。 DEBUG陷阱在这方面更具多功能性。 – lynxlynxlynx 2012-07-11 13:24:10

+0

就是这样;这个历史观念也不太好,因为它有副作用;你不想总是保存你的历史。为什么你不想检查历史输出? – 2012-07-11 13:35:09

相关问题