From b63339088fd3c6e2d20b3bab47cd73d31ab821e2 Mon Sep 17 00:00:00 2001 From: me Date: Tue, 20 Feb 2024 14:33:46 +0100 Subject: [PATCH 1/8] feat(completions/ssh): add support for ssh completion using files in .ssh/config.d too --- completions/ssh.completion.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index fe01b1fe2..f676c0fb5 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -5,6 +5,7 @@ _omb_module_require lib:omb-completion function _omb_completion_ssh { local cur + local file_in_config_d _omb_completion_reassemble_breaks : if [[ $cur == *@* ]] ; then @@ -18,6 +19,13 @@ function _omb_completion_ssh { COMPREPLY=($(compgen -W "$(grep ^Host "$HOME/.ssh/config" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) fi + # parse all defined hosts from .ssh/config.d/* + if [[ -d $HOME/.ssh/config.d ]]; then + for file_in_config_d in "$HOME/.ssh/config.d/"* ;do + [[ -s "$file_in_config_d" ]] &&COMPREPLY+=($(compgen -W "$(grep ^Host "$file_in_config_d" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) + done + fi + # parse all hosts found in .ssh/known_hosts if [[ -r $HOME/.ssh/known_hosts ]]; then if grep -v -q -e '^ ssh-rsa' "$HOME/.ssh/known_hosts" ; then From 084a3026b1c4934b2c331ab188fc7c79d0c36458 Mon Sep 17 00:00:00 2001 From: me Date: Thu, 22 Feb 2024 09:37:02 +0100 Subject: [PATCH 2/8] fix(completions/ssh): detect Include option in ~/.ssh/config and parse content files for completion --- completions/ssh.completion.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index f676c0fb5..c8377e58a 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -5,7 +5,7 @@ _omb_module_require lib:omb-completion function _omb_completion_ssh { local cur - local file_in_config_d + local additional_include_defined_file _omb_completion_reassemble_breaks : if [[ $cur == *@* ]] ; then @@ -19,12 +19,11 @@ function _omb_completion_ssh { COMPREPLY=($(compgen -W "$(grep ^Host "$HOME/.ssh/config" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) fi - # parse all defined hosts from .ssh/config.d/* - if [[ -d $HOME/.ssh/config.d ]]; then - for file_in_config_d in "$HOME/.ssh/config.d/"* ;do - [[ -s "$file_in_config_d" ]] &&COMPREPLY+=($(compgen -W "$(grep ^Host "$file_in_config_d" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) - done - fi + # check if .ssh/config contains Include options + for additional_include_defined_file in $(awk -F' ' '/^Înclude/{print $2}' 2>/dev/null) ;do + # parse all defined hosts from that file + [[ -s "$additional_include_defined_file" ]] &&COMPREPLY+=($(compgen -W "$(grep ^Host "$additional_include_defined_file" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) + done # parse all hosts found in .ssh/known_hosts if [[ -r $HOME/.ssh/known_hosts ]]; then From d9711d8637425e5c12e2c8a39daaf35ed0bbad67 Mon Sep 17 00:00:00 2001 From: me Date: Thu, 22 Feb 2024 10:27:44 +0100 Subject: [PATCH 3/8] feat(completions/ssh): support globbing Include files and correct typo Co-authored-by: Koichi Murase --- completions/ssh.completion.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index c8377e58a..57fd125a9 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -5,6 +5,7 @@ _omb_module_require lib:omb-completion function _omb_completion_ssh { local cur + local additional_include_option local additional_include_defined_file _omb_completion_reassemble_breaks : @@ -20,9 +21,14 @@ function _omb_completion_ssh { fi # check if .ssh/config contains Include options - for additional_include_defined_file in $(awk -F' ' '/^Înclude/{print $2}' 2>/dev/null) ;do - # parse all defined hosts from that file - [[ -s "$additional_include_defined_file" ]] &&COMPREPLY+=($(compgen -W "$(grep ^Host "$additional_include_defined_file" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) + for additional_include_option in $(awk -F' ' '/^Include/{print $2}' "$HOME/.ssh/config" 2>/dev/null) ;do + # relative or absolute path, if relative transforms to absolute + [[ "${additional_include_option:0:1}" == "/" ]] ||additional_include_option="$HOME/.ssh/$additional_include_option" + # for loop to interpret possible globbing + for additional_include_defined_file in $additional_include_option ;do + # parse all defined hosts from that file + [[ -s "$additional_include_defined_file" ]] &&COMPREPLY+=($(compgen -W "$(grep ^Host "$additional_include_defined_file" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) + done done # parse all hosts found in .ssh/known_hosts From 02a5acc390707d4e6a2c07b6fb095fbb1669e71e Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 28 Apr 2024 13:21:12 +0900 Subject: [PATCH 4/8] fix(completions/ssh): use "_omb_util_{split,expand_glob}" and add refactoring and performance improvements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(completions/ssh): move declaration of local variables * perf(completions/ssh): include the for-loop inside the if-statement of ~/.ssh/config * refactor(completions/ssh): use glob matching * perf(completions/ssh): read config files in a single grep&awk * perf(completions/ssh): match ^Host by awk to reduce use of grep * fix(completions/ssh): use "_omb_util_{split,expand_glob}" for safer expansions * refactor(completions/ssh): rename local variables * refactor(completions/ssh): perform pathname expansion at once * fix(completions/ssh): correct to array var in relative or absolute transform loop Co-authored-by: Stéphane Juventy Co-authored-by: me --- completions/ssh.completion.sh | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index 57fd125a9..94f6efaa6 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -5,8 +5,6 @@ _omb_module_require lib:omb-completion function _omb_completion_ssh { local cur - local additional_include_option - local additional_include_defined_file _omb_completion_reassemble_breaks : if [[ $cur == *@* ]] ; then @@ -15,21 +13,32 @@ function _omb_completion_ssh { local -a options=(-- "$cur") fi + local IFS=$'\n' + # parse all defined hosts from .ssh/config if [[ -r $HOME/.ssh/config ]]; then - COMPREPLY=($(compgen -W "$(grep ^Host "$HOME/.ssh/config" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) - fi + local -a config_files=("$HOME/.ssh/config") + + # check if .ssh/config contains Include options + local -a include_patterns + _omb_util_split include_patterns "$(awk -F' ' '/^Include/{print $2}' "$HOME/.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 - # check if .ssh/config contains Include options - for additional_include_option in $(awk -F' ' '/^Include/{print $2}' "$HOME/.ssh/config" 2>/dev/null) ;do - # relative or absolute path, if relative transforms to absolute - [[ "${additional_include_option:0:1}" == "/" ]] ||additional_include_option="$HOME/.ssh/$additional_include_option" - # for loop to interpret possible globbing - for additional_include_defined_file in $additional_include_option ;do + # 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 "$additional_include_defined_file" ]] &&COMPREPLY+=($(compgen -W "$(grep ^Host "$additional_include_defined_file" | awk '{for (i=2; i<=NF; i++) print $i}' )" "${options[@]}")) + [[ -s "$include_file" ]] && config_files+=("$include_file") done - done + + 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 $HOME/.ssh/known_hosts ]]; then From b788bff0e7ae5098937264f1defd0410d9abd347 Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 28 Apr 2024 14:25:32 +0900 Subject: [PATCH 5/8] refactor(completions/ssh): use tilde expansions --- completions/ssh.completion.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index 94f6efaa6..f503ed626 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -16,12 +16,12 @@ function _omb_completion_ssh { local IFS=$'\n' # parse all defined hosts from .ssh/config - if [[ -r $HOME/.ssh/config ]]; then - local -a config_files=("$HOME/.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}' "$HOME/.ssh/config" 2>/dev/null)" $'\n' + _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 @@ -41,9 +41,9 @@ function _omb_completion_ssh { fi # parse all hosts found in .ssh/known_hosts - if [[ -r $HOME/.ssh/known_hosts ]]; then - if grep -v -q -e '^ ssh-rsa' "$HOME/.ssh/known_hosts" ; then - COMPREPLY+=($(compgen -W "$( awk '{print $1}' "$HOME/.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[@]}")) + 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[@]}")) fi fi From 8c5546613d12a291a586e2c46bbb04c64829f09d Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 28 Apr 2024 13:49:06 +0900 Subject: [PATCH 6/8] docs(lib/utils): describe "_omb_util_{split,expand_glob}" in code comment --- lib/utils.sh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/utils.sh b/lib/utils.sh index 236ba5177..cba8a4681 100644 --- a/lib/utils.sh +++ b/lib/utils.sh @@ -366,6 +366,13 @@ function _omb_util_add_prompt_command { } ## @fn _omb_util_split array str [sep] +## Split STR with SEP in a safe way and store the result in ARRAY. +## @param[out] array +## The name of an array variable to which the split result is stored. +## @param[in] str +## The string to split +## @param[in,opt] +## The set of separator characters. The default is ' '. function _omb_util_split { local __set=$- IFS=${3:-$' \t\n'} set -f @@ -374,6 +381,13 @@ function _omb_util_split { return 0 } +## @fn _omb_util_glob_expand array glob +## Perform the pathname expansion of a glob pattern GLOB in a safe way and +## store the filenames in ARRAY. +## @param[out] array +## The name of an array variable to which the filenames are stored. +## @param[in] glob +## The glob pattern that is attempted to match filenames function _omb_util_glob_expand { local __set=$- __shopt __gignore=$GLOBIGNORE _omb_util_get_shopt failglob nullglob extglob From ad14b874fd20f46406eee57c637c74c29376e31e Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Sun, 28 Apr 2024 14:26:23 +0900 Subject: [PATCH 7/8] fix(lib/utils): remove duplicate function "_omb_util_split" --- lib/utils.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/utils.sh b/lib/utils.sh index cba8a4681..d2e01b546 100644 --- a/lib/utils.sh +++ b/lib/utils.sh @@ -414,14 +414,6 @@ function _omb_util_glob_expand { return 0 } -function _omb_util_split { - local __set=$- IFS=${3:-$' \t\n'} - set -f - eval -- "$1=(\$2)" - [[ $__set == *f* ]] || set +f - return 0 -} - function _omb_util_alias { case ${OMB_DEFAULT_ALIASES:-enable} in (disable) return 0 ;; From c2ca9be0180d895e4c7b80bfaf17396aa9ad698b Mon Sep 17 00:00:00 2001 From: Koichi Murase Date: Thu, 2 May 2024 09:26:02 +0900 Subject: [PATCH 8/8] style(completions/ssh): clean up * style(completions/ssh): normalize quoting --- completions/ssh.completion.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/completions/ssh.completion.sh b/completions/ssh.completion.sh index f503ed626..7e0ee6d94 100644 --- a/completions/ssh.completion.sh +++ b/completions/ssh.completion.sh @@ -7,10 +7,11 @@ function _omb_completion_ssh { local cur _omb_completion_reassemble_breaks : + local -a options if [[ $cur == *@* ]] ; then - local -a options=(-P "${cur%%@*}@" -- "${cur#*@}") + options=(-P "${cur%%@*}@" -- "${cur#*@}") else - local -a options=(-- "$cur") + options=(-- "$cur") fi local IFS=$'\n' @@ -34,7 +35,7 @@ function _omb_completion_ssh { local include_file for include_file in "${include_files[@]}";do # parse all defined hosts from that file - [[ -s "$include_file" ]] && config_files+=("$include_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[@]}"))