From c36a9507554d092fa3300b764fc542323bc1e83d Mon Sep 17 00:00:00 2001 From: plasmastorm Date: Wed, 8 May 2024 19:31:51 +0100 Subject: [PATCH 1/5] completions/ssh: Include system ssh config and known_hosts for hosts --- completions/ssh.completion.sh | 63 +++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index 7e0ee6d94..fe44acf93 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -16,37 +16,42 @@ 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 - - COMPREPLY+=($(compgen -W "$(awk '/^Host/ {for (i=2; i<=NF; i++) print $i}' "${config_files[@]}")" "${options[@]}")) - fi + for base_config_file in ~/.ssh/config /etc/ssh/ssh_config; do + # parse all defined hosts from config file + if [[ -r $base_config_file ]]; then + local basedir + basedir=$(dirname $base_config_file) + local -a 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 - # 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[@]}")) + COMPREPLY+=($(compgen -W "$(awk '/^Host/ {for (i=2; i<=NF; i++) print $i}' "${config_files[@]}")" "${options[@]}")) fi - fi + done + + for known_hosts_file in ~/.ssh/known_hosts /etc/ssh/ssh_known_hosts; do + if [[ -r $known_hosts_file ]]; then + if grep -v -q -e '^ ssh-rsa' "${known_hosts_file}"; then + COMPREPLY+=($(compgen -W "$( awk '{print $1}' "${known_hosts_file}" | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" "${options[@]}")) + fi + fi + done # parse hosts defined in /etc/hosts if [[ -r /etc/hosts ]]; then From d20b4461aeed437a246c1f07db48e37b787eedde Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 16 May 2024 18:57:23 +0900 Subject: [PATCH 2/5] fix(completions/ssh): fix up small issues * fix(completions/ssh): localize variables * fix(completions/ssh): quote parameter expansions * perf(completions/ssh): use parameter expansion to get directory name --- completions/ssh.completion.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index fe44acf93..bf0fe28f6 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -16,16 +16,17 @@ function _omb_completion_ssh { local IFS=$'\n' + local base_config_file for base_config_file in ~/.ssh/config /etc/ssh/ssh_config; do # parse all defined hosts from config file if [[ -r $base_config_file ]]; then local basedir - basedir=$(dirname $base_config_file) + basedir=${base_config_file%/*} local -a 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' + _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 @@ -45,6 +46,7 @@ function _omb_completion_ssh { fi done + local known_hosts_file for known_hosts_file in ~/.ssh/known_hosts /etc/ssh/ssh_known_hosts; do if [[ -r $known_hosts_file ]]; then if grep -v -q -e '^ ssh-rsa' "${known_hosts_file}"; then From ce2601f8ea9f2824d4dac8460f2965036ce9ba9a Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 16 May 2024 19:00:01 +0900 Subject: [PATCH 3/5] style(completions/ssh): normalize styles --- completions/ssh.completion.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index bf0fe28f6..269a6691c 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -30,7 +30,7 @@ function _omb_completion_ssh { 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]} + [[ ${include_patterns[i]} == /* ]] || include_patterns[i]=$basedir/${include_patterns[i]} done # interpret possible globbing @@ -49,15 +49,15 @@ function _omb_completion_ssh { local known_hosts_file for known_hosts_file in ~/.ssh/known_hosts /etc/ssh/ssh_known_hosts; do if [[ -r $known_hosts_file ]]; then - if grep -v -q -e '^ ssh-rsa' "${known_hosts_file}"; then - COMPREPLY+=($(compgen -W "$( awk '{print $1}' "${known_hosts_file}" | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" "${options[@]}")) + if grep -v -q -e '^ ssh-rsa' "$known_hosts_file"; then + COMPREPLY+=($(compgen -W "$(awk '{print $1}' "${known_hosts_file}" | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" "${options[@]}")) fi fi done # 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 From cc4151524dad0f6401f63efa22115b8f74f6f38b Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 16 May 2024 19:05:09 +0900 Subject: [PATCH 4/5] perf(completions/ssh): extract hostnames with a single spawn for each config type --- completions/ssh.completion.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index 269a6691c..af6061586 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -16,13 +16,14 @@ function _omb_completion_ssh { local IFS=$'\n' + local -a config_files=() local base_config_file for base_config_file in ~/.ssh/config /etc/ssh/ssh_config; do # parse all defined hosts from config file if [[ -r $base_config_file ]]; then local basedir basedir=${base_config_file%/*} - local -a config_files=("$base_config_file") + config_files+=("$base_config_file") # check if config file contains Include options local -a include_patterns @@ -41,19 +42,24 @@ function _omb_completion_ssh { # parse all defined hosts from that file [[ -s $include_file ]] && config_files+=("$include_file") done - - COMPREPLY+=($(compgen -W "$(awk '/^Host/ {for (i=2; i<=NF; i++) print $i}' "${config_files[@]}")" "${options[@]}")) fi done + if ((${#config_files[@]} != 0)); then + COMPREPLY+=($(compgen -W "$(awk '/^Host/ {for (i=2; i<=NF; i++) print $i}' "${config_files[@]}")" "${options[@]}")) + fi + 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 if grep -v -q -e '^ ssh-rsa' "$known_hosts_file"; then - COMPREPLY+=($(compgen -W "$(awk '{print $1}' "${known_hosts_file}" | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" "${options[@]}")) + known_hosts_files+=("$known_hosts_file") fi fi done + if ((${#known_hosts_files[@]} != 0)); then + COMPREPLY+=($(compgen -W "$(awk '{print $1}' "${known_hosts_files[@]}" | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" "${options[@]}")) + fi # parse hosts defined in /etc/hosts if [[ -r /etc/hosts ]]; then From e155f9a75bc56fad6e84cd4543af5d7c60680762 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Fri, 17 May 2024 13:12:22 +0900 Subject: [PATCH 5/5] perf(completions/ssh): filter known_hosts in awk --- completions/ssh.completion.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index af6061586..f47759361 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -52,13 +52,15 @@ function _omb_completion_ssh { local known_hosts_file for known_hosts_file in ~/.ssh/known_hosts /etc/ssh/ssh_known_hosts; do if [[ -r $known_hosts_file ]]; then - if grep -v -q -e '^ ssh-rsa' "$known_hosts_file"; then - known_hosts_files+=("$known_hosts_file") - fi + known_hosts_files+=("$known_hosts_file") fi done if ((${#known_hosts_files[@]} != 0)); then - COMPREPLY+=($(compgen -W "$(awk '{print $1}' "${known_hosts_files[@]}" | grep -v ^\| | cut -d, -f 1 | sed -e 's/\[//g' | sed -e 's/\]//g' | cut -d: -f1 | grep -v ssh-rsa)" "${options[@]}")) + COMPREPLY+=($(compgen -W "$(awk ' + $1 !~ /^\|/ { + gsub(/[][]|[,:].*/, "", $1); + if ($1 !~ /ssh-rsa/) print $1; + }' "${known_hosts_files[@]}")" "${options[@]}")) fi # parse hosts defined in /etc/hosts