mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2026-05-22 04:51:12 +02:00
feat(ssh): Load hosts in other ssh config files
If the ~/.ssh/config contains `Include` directives, it'd be better to parse the target config files if possible. This commit implements that. The included config can also have Include directives, but it's not parsed because of possibility of infinite loop, for now.
This commit is contained in:
parent
3604dc23e0
commit
e7620cac3c
2 changed files with 49 additions and 15 deletions
|
|
@ -1,7 +1,8 @@
|
|||
# ssh plugin
|
||||
|
||||
This plugin provides host completion based off of your `~/.ssh/config` file, and adds
|
||||
some utility functions to work with SSH keys.
|
||||
This plugin provides host completion based off of your `~/.ssh/config` file,
|
||||
and adds some utility functions to work with SSH keys. If the `~/.ssh/config`
|
||||
contains `Include` directives, the plugin also parse hosts in related files.
|
||||
|
||||
To use it, add `ssh` to the plugins array in your zshrc file:
|
||||
|
||||
|
|
|
|||
|
|
@ -2,20 +2,53 @@
|
|||
# Take all host sections in .ssh/config and offer them for
|
||||
# completion as hosts (e.g. for ssh, rsync, scp and the like)
|
||||
# Filter out wildcard host sections.
|
||||
_ssh_configfile="$HOME/.ssh/config"
|
||||
if [[ -f "$_ssh_configfile" ]]; then
|
||||
_ssh_hosts=($(
|
||||
grep -E '^Host.*' "$_ssh_configfile" |\
|
||||
# If the .ssh/config has Include directives, load them too.
|
||||
function _load_ssh_hosts {
|
||||
local conf="$1"
|
||||
if [[ -f "$conf" ]]; then
|
||||
local _ssh_hosts=($(
|
||||
grep -E '^Host[[:space:]]' "$conf" |\
|
||||
awk '{for (i=2; i<=NF; i++) print $i}' |\
|
||||
sort |\
|
||||
uniq |\
|
||||
grep -v '^*' |\
|
||||
sed -e 's/\.*\*$//'
|
||||
))
|
||||
echo "${_ssh_hosts[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
# XXX: We could make it recursive but won't implement for now
|
||||
function _find_include_files {
|
||||
local conf="$1"
|
||||
if [[ -f "$conf" ]]; then
|
||||
grep -E '^Include[[:space:]]' "$conf" |\
|
||||
awk '{for (i=2; i<=NF; i++) print $i}' |\
|
||||
sort |\
|
||||
uniq |\
|
||||
grep -v '^*' |\
|
||||
sed -e 's/\.*\*$//'
|
||||
))
|
||||
zstyle ':completion:*:hosts' hosts $_ssh_hosts
|
||||
unset _ssh_hosts
|
||||
fi
|
||||
unset _ssh_configfile
|
||||
sed -e 's/^"\(.*\)"$/\1/' -e "s/^'\(.*\)'\$/\\1/"
|
||||
fi
|
||||
}
|
||||
|
||||
all_hosts=($(_load_ssh_hosts "$HOME/.ssh/config"))
|
||||
|
||||
_find_include_files "$HOME/.ssh/config" | while read include_file; do
|
||||
# omz doesn't know "~" directory
|
||||
if [[ "$include_file" == ~* ]]; then
|
||||
include_file="${HOME}${include_file:1}"
|
||||
# Per ssh_config(5), relative paths are resolved against ~/.ssh
|
||||
elif [[ "$include_file" != /* ]]; then
|
||||
include_file="$HOME/.ssh/$include_file"
|
||||
fi
|
||||
if [[ -f "$include_file" ]]; then
|
||||
hosts=($(_load_ssh_hosts "$include_file"))
|
||||
all_hosts+=("${hosts[@]}")
|
||||
fi
|
||||
done
|
||||
|
||||
zstyle ':completion:*:hosts' hosts "${all_hosts[@]}"
|
||||
|
||||
unset -f _load_ssh_hosts
|
||||
unset -f _find_include_files
|
||||
unset all_hosts
|
||||
|
||||
############################################################
|
||||
# Remove host key from known hosts based on a host section
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue