/bash_completion_lib/include/_known_hosts
http://github.com/brinkman83/bashrc · #! · 138 lines · 124 code · 14 blank · 0 comment · 0 complexity · d93ae1561e444fef83b5ca1b99e4c123 MD5 · raw file
- # This function performs host completion based on ssh's known_hosts files,
- # defaulting to standard host completion if they don't exist.
- # Arguments: -a Use aliases
- # -c Use `:' suffix
- # -F configfile Use `configfile' for configuration settings
- _known_hosts()
- {
- local configfile cur curd ocur user suffix aliases global_kh user_kh hosts i host
- local -a kh khd config
- COMPREPLY=()
- cur=`_get_cword`
- ocur=$cur
- local OPTIND=1
- while getopts "acF:" flag "$@"; do
- case $flag in
- a) aliases='yes' ;;
- c) suffix=':' ;;
- F) configfile="$OPTARG" ;;
- esac
- done
- [[ $cur == *@* ]] && user=${cur%@*}@ && cur=${cur#*@}
- kh=()
- # ssh config files
- if [ -n "$configfile" ]; then
- [ -r "$configfile" ] &&
- config=( "${config[@]}" "$configfile" )
- else
- [ -r /etc/ssh/ssh_config ] &&
- config=( "${config[@]}" "/etc/ssh/ssh_config" )
- [ -r "${HOME}/.ssh/config" ] &&
- config=( "${config[@]}" "${HOME}/.ssh/config" )
- [ -r "${HOME}/.ssh2/config" ] &&
- config=( "${config[@]}" "${HOME}/.ssh2/config" );
- fi
- if [ ${#config[@]} -gt 0 ]; then
- # expand path (if present) to global known hosts file
- global_kh=$( eval echo "$( sed -ne 's/^[ \t]*[Gg][Ll][Oo][Bb][Aa][Ll][Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee]['"$'\t '"']*\(.*\)$/\1/p' "${config[@]}" )" )
- # expand path (if present) to user known hosts file
- user_kh=$( eval echo "$( sed -ne 's/^[ \t]*[Uu][Ss][Ee][Rr][Kk][Nn][Oo][Ww][Nn][Hh][Oo][Ss][Tt][Ss][Ff][Ii][Ll][Ee]['"$'\t '"']*\(.*\)$/\1/p' "${config[@]}" )" )
- fi
- # Global known_hosts files
- [ -r "$global_kh" ] &&
- kh=( "${kh[@]}" "$global_kh" )
- if [ -z "$configfile" ]; then
- [ -r /etc/ssh/ssh_known_hosts ] &&
- kh=( "${kh[@]}" /etc/ssh/ssh_known_hosts )
- [ -r /etc/ssh/ssh_known_hosts2 ] &&
- kh=( "${kh[@]}" /etc/ssh/ssh_known_hosts2 )
- [ -r /etc/known_hosts ] &&
- kh=( "${kh[@]}" /etc/known_hosts )
- [ -r /etc/known_hosts2 ] &&
- kh=( "${kh[@]}" /etc/known_hosts2 )
- [ -d /etc/ssh2/knownhosts ] &&
- khd=( "${khd[@]}" /etc/ssh2/knownhosts/*pub )
- fi
- # User known_hosts files
- [ -r "$user_kh" ] &&
- kh=( "${kh[@]}" "$user_kh" )
- if [ -z "$configfile" ]; then
- [ -r ~/.ssh/known_hosts ] &&
- kh=( "${kh[@]}" ~/.ssh/known_hosts )
- [ -r ~/.ssh/known_hosts2 ] &&
- kh=( "${kh[@]}" ~/.ssh/known_hosts2 )
- [ -d ~/.ssh2/hostkeys ] &&
- khd=( "${khd[@]}" ~/.ssh2/hostkeys/*pub )
- fi
- # If we have known_hosts files to use
- if [ ${#kh[@]} -gt 0 -o ${#khd[@]} -gt 0 -o -n "$configfile" ]; then
- # Escape slashes and dots in paths for awk
- cur=${cur//\//\\\/}
- cur=${cur//\./\\\.}
- curd=$cur
- if [[ "$cur" == [0-9]*.* ]]; then
- # Digits followed by a dot - just search for that
- cur="^$cur.*"
- elif [[ "$cur" == [0-9]* ]]; then
- # Digits followed by no dot - search for digits followed
- # by a dot
- cur="^$cur.*\."
- elif [ -z "$cur" ]; then
- # A blank - search for a dot or an alpha character
- cur="[a-z.]"
- else
- cur="^$cur"
- fi
- if [ ${#kh[@]} -gt 0 ]; then
- # FS needs to look for a comma separated list
- COMPREPLY=( $( awk 'BEGIN {FS=","}
- /^[^|]/ {for (i=1; i<=2; ++i) { \
- gsub(" .*$", "", $i); \
- if ($i ~ /'$cur'/) {print $i} \
- }}' "${kh[@]}" 2>/dev/null ) )
- fi
- if [ ${#khd[@]} -gt 0 ]; then
- # Needs to look for files called
- # .../.ssh2/key_22_<hostname>.pub
- # dont fork any processes, because in a cluster environment,
- # there can be hundreds of hostkeys
- for i in "${khd[@]}" ; do
- if [[ "$i" == *key_22_$curd*.pub ]] && [ -r "$i" ] ; then
- host=${i/#*key_22_/}
- host=${host/%.pub/}
- COMPREPLY=( "${COMPREPLY[@]}" $host )
- fi
- done
- fi
- # append any available aliases from config files
- if [ ${#config[@]} -gt 0 ] && [ -n "$aliases" ]; then
- local host_aliases=$( sed -ne 's/^[ \t]*[Hh][Oo][Ss][Tt]\([Nn][Aa][Mm][Ee]\)\?['"$'\t '"']\+\([^#*?]*\)\(#.*\)\?$/\2/p' "${config[@]}" )
- hosts=$( compgen -W "$host_aliases" -- $ocur )
- COMPREPLY=( "${COMPREPLY[@]}" $hosts )
- fi
-
- # Now add results of normal hostname completion
- COMPREPLY=( "${COMPREPLY[@]}" $( compgen -A hostname -- $ocur ) )
- # apply suffix
- for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
- COMPREPLY[i]=$user${COMPREPLY[i]}$suffix
- done
- elif [ -z "$configfile" ]; then
- # Just do normal hostname completion
- COMPREPLY=( $( compgen -A hostname -S "$suffix" -- $cur ) )
- fi
- return 0
- } # _known_hosts()