In zsh I can open any file with a special suffix or extension like .log or .txt with a program with typing its file name only
$ alias -s txt=nano
$ word.txt
That open the file word.txt with nano. How can I do this in bash?
In zsh I can open any file with a special suffix or extension like .log or .txt with a program with typing its file name only
$ alias -s txt=nano
$ word.txt
That open the file word.txt with nano. How can I do this in bash?
How about exec zsh
?
But this feature can actually be implemented in bash (since version 4.0; OSX users, see the previous paragraph). Kind of. When bash encounters a command that isn't found in the PATH
, it runs a function called command_not_found_handle
. You can write a function that attempts to open the file if it's a file in the current directory.
typeset -A extension_aliases
command_not_found_handle () {
if [[ $# -eq 1 && -e $1 && $1 = *.* ]]; then
local handler="${extension_aliases[${1##*.}]}"
if [[ -n $local_handler ]]; then
eval "$local_handler \"\$@\""
return
fi
fi
return 127
}
Instead of alias -s txt=nano
, use extension_aliases[txt]=nano
.
There are limitations to this approach. The file must be in the current directory, because command_not_found_handle
is only invoked with a command name that doesn't contain a slash. Also you won't get completion for the file name.
It is a lot simpler to use existing mechanisms:
xdg-open word.txt
or on Debian and derivatives
see word.txt
You get many benefits: there's already a system database that maps extensions to programs, completion will work, and it doesn't require any special handling from the shell. It does require a bit more typing, but you can define a one-character alias for it (you'll need a space after it), or a key binding that inserts xdg-open
at the beginning of the line:
bind -x '"\eo": READLINE_LINE="xdg-open $READLINE_LINE"; READLINE_POINT+=9'