Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

completions/ssh: Include global ssh hosts #569

Merged
merged 5 commits into from
May 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 41 additions & 26 deletions completions/ssh.completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,56 @@ function _omb_completion_ssh {

local IFS=$'\n'

# parse all defined hosts from .ssh/config
if [[ -r ~/.ssh/config ]]; then
local -a config_files=(~/.ssh/config)

# check if .ssh/config contains Include options
local -a include_patterns
_omb_util_split include_patterns "$(awk -F' ' '/^Include/{print $2}' ~/.ssh/config 2>/dev/null)" $'\n'
local i
for i in "${!include_patterns[@]}"; do
# relative or absolute path, if relative transforms to absolute
[[ ${include_patterns[i]} == /* ]] || include_patterns[i]=~/.ssh/${include_patterns[i]}
done

# interpret possible globbing
local -a include_files
_omb_util_glob_expand include_files '${include_patterns[*]}'
local include_file
for include_file in "${include_files[@]}";do
# parse all defined hosts from that file
[[ -s $include_file ]] && config_files+=("$include_file")
done
local -a config_files=()
local base_config_file
for base_config_file in ~/.ssh/config /etc/ssh/ssh_config; do
akinomyoga marked this conversation as resolved.
Show resolved Hide resolved
# parse all defined hosts from config file
if [[ -r $base_config_file ]]; then
local basedir
basedir=${base_config_file%/*}
config_files+=("$base_config_file")

# check if config file contains Include options
local -a include_patterns
_omb_util_split include_patterns "$(awk -F' ' '/^Include/{print $2}' "$base_config_file" 2>/dev/null)" $'\n'
local i
for i in "${!include_patterns[@]}"; do
# relative or absolute path, if relative transforms to absolute
[[ ${include_patterns[i]} == /* ]] || include_patterns[i]=$basedir/${include_patterns[i]}
done

# interpret possible globbing
local -a include_files
_omb_util_glob_expand include_files '${include_patterns[*]}'
local include_file
for include_file in "${include_files[@]}";do
# parse all defined hosts from that file
[[ -s $include_file ]] && config_files+=("$include_file")
done
fi
done
if ((${#config_files[@]} != 0)); then
COMPREPLY+=($(compgen -W "$(awk '/^Host/ {for (i=2; i<=NF; i++) print $i}' "${config_files[@]}")" "${options[@]}"))
fi

# parse all hosts found in .ssh/known_hosts
if [[ -r ~/.ssh/known_hosts ]]; then
if grep -v -q -e '^ ssh-rsa' ~/.ssh/known_hosts; then
COMPREPLY+=($(compgen -W "$( awk '{print $1}' ~/.ssh/known_hosts | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" "${options[@]}"))
local -a known_hosts_files=()
local known_hosts_file
for known_hosts_file in ~/.ssh/known_hosts /etc/ssh/ssh_known_hosts; do
if [[ -r $known_hosts_file ]]; then
known_hosts_files+=("$known_hosts_file")
fi
done
if ((${#known_hosts_files[@]} != 0)); then
COMPREPLY+=($(compgen -W "$(awk '
$1 !~ /^\|/ {
gsub(/[][]|[,:].*/, "", $1);
if ($1 !~ /ssh-rsa/) print $1;
}' "${known_hosts_files[@]}")" "${options[@]}"))
fi

# parse hosts defined in /etc/hosts
if [[ -r /etc/hosts ]]; then
COMPREPLY+=($(compgen -W "$( grep -v '^[[:space:]]*$' /etc/hosts | grep -v '^#' | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}"))
COMPREPLY+=($(compgen -W "$(grep -v '^[[:space:]]*$' /etc/hosts | grep -v '^#' | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}"))
fi

_omb_completion_resolve_breaks
Expand Down
Loading