Skip to content

Instantly share code, notes, and snippets.

@pv8
Last active March 16, 2017 13:06
Show Gist options
  • Save pv8/7b0119e3a0013d7a088ad2227c8f353d to your computer and use it in GitHub Desktop.
Save pv8/7b0119e3a0013d7a088ad2227c8f353d to your computer and use it in GitHub Desktop.
Simple patch to apply on Homebrew bash-completion in order to locate ssh included files in configs (based on https://github.com/scop/bash-completion/releases/tag/2.5)
--- bash_completion 2017-02-09 18:29:54.000000000 -0200
+++ bash_completion_new 2017-02-09 18:20:19.000000000 -0200
@@ -1205,6 +1205,39 @@
_known_hosts_real $options "$(_get_cword :)"
} # _known_hosts()
+# Helper function to locate ssh included files in configs
+# This function look for the "Include" keyword in ssh config files and include
+# them recursively adding each result to the config variable
+_included_ssh_config_files()
+{
+ [[ $# -lt 1 ]] && echo "error: $FUNCNAME: missing mandatory argument CONFIG"
+ local configfile i f
+ configfile=$1
+ local included=$( command sed -ne 's/^[[:blank:]]*[Ii][Nn][Cc][Ll][Uu][Dd][Ee][[:blank:]]\{1,\}\([^#%]*\)\(#.*\)\{0,1\}$/\1/p' "${configfile}" )
+ for i in ${included[@]}; do
+ # Check the origin of $configfile to complete relative included paths on included
+ # files according to ssh_config(5):
+ # "[...] Files without absolute paths are assumed to be in ~/.ssh if included in a user
+ # configuration file or /etc/ssh if included from the system configuration file.[...]"
+ if ! [[ "$i" =~ ^\~.*|^\/.* ]]; then
+ if [[ "$configfile" =~ ^\/etc\/ssh.* ]]; then
+ i="/etc/ssh/$i"
+ else
+ i="$HOME/.ssh/$i"
+ fi
+ fi
+ __expand_tilde_by_ref i
+ # In case the expanded variable contains multiple paths
+ for f in ${i}; do
+ if [ -r $f ]; then
+ config+=( "$f" )
+ # The Included file is processed to look for Included files in itself
+ _included_ssh_config_files $f
+ fi
+ done
+ done
+} # _included_ssh_config_files()
+
# Helper function for completing _known_hosts.
# This function performs host completion based on ssh's config and known_hosts
# files, as well as hostnames reported by avahi-browse if
@@ -1251,6 +1284,11 @@
done
fi
+ # "Include" keyword in ssh config files
+ for i in "${config[@]}"; do
+ _included_ssh_config_files "$i"
+ done
+
# Known hosts files from configs
if [ ${#config[@]} -gt 0 ]; then
local OIFS=$IFS IFS=$'\n'
@pv8
Copy link
Author

pv8 commented Feb 9, 2017

The goal here is to make auto completion locate ssh config files included in ~/.ssh/config (using Include keyword) without upgrading macOS default bash in order to use bash-completion2 (which requires bash v4.x).

To apply this patch to bash-completion (installed via Homebrew):

$ curl -s https://gist.githubusercontent.com/pv8/7b0119e3a0013d7a088ad2227c8f353d/raw/3db6a7fa276dfe8c3ae7230f0e08f37ad1bdad07/bash_completion.ssh_includes.patch | patch $(python -c 'import os.path; print(os.path.realpath("/usr/local/etc/bash_completion"))')

To revert this patch (patch -R):

$ curl -s https://gist.githubusercontent.com/pv8/7b0119e3a0013d7a088ad2227c8f353d/raw/3db6a7fa276dfe8c3ae7230f0e08f37ad1bdad07/bash_completion.ssh_includes.patch | patch -R $(python -c 'import os.path; print(os.path.realpath("/usr/local/etc/bash_completion"))')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment