ohmyzsh
ohmyzsh copied to clipboard
ssh completion broken in last version (takes always an entry in /etc/hosts if present)
Since a few days (last update) my oh-my-zsh fails when typing the beginning of a Hostname value in .config/ssh. For example, in my .ssh/config I have:
Host home-dev-1
hostname X.X.X.X
user xxxxx
and in my /etc/hosts I have:
1.2.3.4 home-test
If I type in the terminal ssh home
and press TAB then I get home-test
(which is an entry in my /etc/hosts).
If there is no entries in my /etc/hosts beginning with "home" then it would get entries in my .ssh/config. But obviously this is not the expected behavior and it is a clear regression.
Hi,
Since #2602 we are using Zsh default completion. I completes both from hosts
and your .ssh/config
.
However, as you apparently noticed, it does not complete the "HostName" values from the config file, but it completes the "Host" values instead. This is a feature: "HostName" is necessarily the FQDN or address of the host, but "Host" is an alias so it can be whatever you want — you can have "Host" be the same as "HostName" if you like.
TL;DR just change
Host home-dev-1
hostname X.X.X.X
to
Host X.X.X.X
hostname X.X.X.X
I don't understand. Two points:
-
bash completion takes the Host field rather than the hostname.
-
In my case hostname is an IP, how can it be useful at all?
Sorry, English is a second language. Let me try again. You wrote:
bash completion takes the Host field rather than the hostname.
Zsh does the same. Since #2602, so does OMZ.
You should be able to complete by typing ssh home-d
and TAB. Is that not working?
OK, let me explain what works and what does not work:
This is my .ssh/config:
Host foo-bar
hostname 127.0.0.1
port 1001
Host test-remote-server
hostname 127.0.0.1
port 1002
and this is my /etc/hosts:
127.0.0.1 test-local-server
- If I type
ssh foo
+ TAB I getssh foo-bar
=> OK - If I type
ssh test
+ TAB I automatically getssh test-local-server
=> Wrong as it should show both "test-local-server" (from /etc/hosts) and "test-remote-server" (from .ssh/config).
So, in case there is an entry in /etc/hosts that matches the given ssh xxxx
then zsh (or omzsh) does not search in .ssh/config.
Aha, I get it now. Let me look into it — maybe Zsh completion is not enough after all.
@blueyed care to weigh in?
Thanks a lot :)
The issue appears to be that if there's a match in /etc/hosts already, the other files are not tried.
It seems like the completion for ssh does not consider /etc/hosts initially. There is only "remote host name". But "ssh host-only-in-etc-hos" gets completed on request.
There might be an option to change this behavior and I've asked in #zsh on IRC, but no quick answer.
Thanks, hope there is a solution. Otherwise my workaround will be adding all my .ssh/config entries into /etc/hosts and setting its hostname in the "hostname" field of .ssh/config (instead of the IP).
@blueyed thanks for your help!
I have the feeling that the following comment:
# If users-hosts matches, we shouldn't complete anything else.
at the end of the ssh completion file has something to do with it, but I need to read chapter 19 of the Zsh manual before I understand how words
and $IPREFIX
work.
@ibc The following was proposed on #zsh:
zstyle -e ':completion:*' hosts 'reply=($(< ~/.hosts))' # and then stick the ones you want in that file
For reference, here's the commit that removed OMZ's previous behavior, which you could adopt partially: https://github.com/robbyrussell/oh-my-zsh/pull/2602/files
@ncanceill
I do not think it's this users-hosts
part that returns already, because it would not look into ~/.ssh/config.
The responsible code is probably the following from the userhost
case:
_alternative \
'hosts:remote host name:_ssh_hosts' \
"$tmp[@]" && ret=0
I could imagine that it falls back to generic hosts
completion, where /etc/hosts is considered also.
@blueyed I will trust you on that, I still do not understand the whole completion file.
However, it seems that the results from ~/.ssh/config
are still taken into account. For instance, if you have localhost
in /etc/hosts
and localtest
in ~/.ssh/config
, then ssh local
will directly complete to localhost
but ssh localt
will still complete to localtest
.
Even though this is a Zsh issue, I find it troublesome that completion from ~/.ssh/config
is overshadowed by completion from /etc/hosts
. Do you think there would be any way to correct the behavior and properly offer choices between all possibilities without rewriting the completion file entirely?
Still seeing this behaviour. Any movement or advice on this? Different ticket to look at?
It's now 2019, this is still a problem.
A somewhat related issue - I also experience a ghost hosts file problem (not sure if that's been reported):
On my Macbook I once had a hosts file entry for someserver.dev
(name adjusted for privacy), while on my newer iMac (some various dot files copied over from my Macbook) that entry does not exist in the hosts file, not even as a commented out line; but still when I type some
and press tab, it'll immediately complete someserver.dev
regardless of how many other servers I have starting with some
in .ssh/config.
I've tried to remove any instances of someserver.dev
from my zsh history file, but still no luck.
To workaround the "ghost hosts file" problem, I've ended up having to just add additional aliases for those servers that don't start with some
, but still my old habits are hard to break, and at least once every few days I'll run into this completion problem.
For host entries that first existed on my iMac, simply commenting them out, and then opening a new terminal session is enough to restore my tab completion, but not exactly a "solution"...
Is there any real solution for this? This issue has been open for almost 5 years now, and there's not so much as a workaround.
Hello 2021, still a problem? :/
I have some hosts in .ssh/config and in hosts, autocomplete always suggest me just from hosts file. Autocompletion on bash works as desired: suggest all matches from hosts and ssh config.
Still no solution for this?
I've created a reward since I use ohmyzsh and I'm still suffering from this problem. I know it's not a great reward (if anyone wants to contribute their bit, feel free) but at least it's something to encourage the solution.