How can I suppress Unix's “command not found”

2019-08-28 01:14发布

My goal: when I type in something that's not a valid Unix command, it gets fed to a special function instead of displaying the "Command not found" message.

I found this post, which got me halfway there.

trap 'if ! type -t $BASH_COMMAND >/dev/null; then special_function $BASH_COMMAND; fi' DEBUG

This allows me to run my special function. However the "Command not found" error still appears afterwards.

Is there any way I can tell Bash to suppress that message? Either in this command, or inside the special function, would be fine. Thanks!

2条回答
甜甜的少女心
2楼-- · 2019-08-28 02:01

The only thing I can think of is redirecting stderr. I don't think it's a great solution but could be a starting point. Something like:

$BASH_COMMAND 3> /tmp/invalid



if [ -f /tmp/invalid ]; then 
  if [ $(grep -c "command not found" /tmp/invalid) -ne 0 ]; 
     special_function $BASH_COMMAND
     rm /tmp/invalid
  fi
fi

Seems a bit clumsy but could work with some adaptation.

查看更多
女痞
3楼-- · 2019-08-28 02:08

In ZSH; this can be achieved by adding this to the .zshrc

setopt debugbeforecmd
trap 'if ! whence -w "$ZSH_DEBUG_CMD" >& /dev/null; then special_function $ZSH_DEBUG_COMMAND;fi' DEBUG
exec 2> >(grep -v "command not found" > /dev/stderr)

This will behave in a very weird way in bash; because bash sends the prompt to stderr ( In effect you will be able to see the prompt and anything you type only after pressing the Enter key ). ZSH on the other hand, handles the prompt and stderr as separate streams.

If you can find a way to make bash to send the prompt to some other location ( say /dev/tty ) something similar will work in bash also.

EDIT :

It seems that bash versions > 4 have a command_notfound_handle function that can do what you want. You can define it in your ~/.bashrc

command_notfound_handle {
   special_function $1
   # The command that was not found is passed as the first argument to the fn
}
查看更多
登录 后发表回答