[Bash-completion-devel] Bug#504141: bash-completion: Improved known_hosts completion with -F support, hosts indented or comment-trailed
Freddy Vulto
fvulto at gmail.com
Fri Oct 31 23:36:46 UTC 2008
Package: bash-completion
Version: 20080705
Severity: normal
Attached are improvements to _known_hosts, ssh, scp and sftp:
- Added support for `-F configfile' to _known_hosts. I've done this especially
to make it easier to configure an ssh testsuite when writing automated tests.
- Allow `Host(Name)' in ssh config file to be indented
- Allow `Host(Name)' in ssh config file to have trailing comment. Note that
SSH allows a comment after `Host' but not after `HostName'. In the latter
case you'll get an error message when trying to scp/ssh/sftp:
garbage at end of line; "#".
Regards,
Freddy Vulto
-- System Information:
Debian Release: 4.0
APT prefers stable
APT policy: (500, 'stable')
Architecture: i386 (i686)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-6-686
Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1)
-------------- next part --------------
=== modified file 'bash_completion'
--- bash_completion 2008-10-10 19:01:59 +0000
+++ bash_completion 2008-10-31 22:47:29 +0000
@@ -2503,28 +2511,42 @@
# 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 cur curd ocur user suffix aliases global_kh user_kh hosts i host
+ 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
- [ "$1" = -a ] || [ "$2" = -a ] && aliases='yes'
- [ "$1" = -c ] || [ "$2" = -c ] && suffix=':'
+ 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
- [ -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" )
+ 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
@@ -2536,29 +2558,33 @@
# Global known_hosts files
[ -r "$global_kh" ] &&
kh=( "${kh[@]}" "$global_kh" )
- [ -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 )
+ 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" )
- [ -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 )
+ 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 ]; then
+ if [ ${#kh[@]} -gt 0 -o ${#khd[@]} -gt 0 -o -n "$configfile" ]; then
# Escape slashes and dots in paths for awk
cur=${cur//\//\\\/}
cur=${cur//\./\\\.}
@@ -2602,7 +2628,7 @@
fi
# append any available aliases from config files
if [ ${#config[@]} -gt 0 ] && [ -n "$aliases" ]; then
- local host_aliases=$( sed -ne 's/^[Hh][Oo][Ss][Tt]\([Nn][Aa][Mm][Ee]\)\?['"$'\t '"']\+\([^*?]*\)$/\2/p' "${config[@]}" )
+ 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
@@ -2614,7 +2640,7 @@
for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
COMPREPLY[i]=$user${COMPREPLY[i]}$suffix
done
- else
+ elif [ -z "$configfile" ]; then
# Just do normal hostname completion
COMPREPLY=( $( compgen -A hostname -S "$suffix" -- $cur ) )
fi
=== modified file 'contrib/ssh'
--- contrib/ssh 2008-09-27 10:58:42 +0000
+++ contrib/ssh 2008-10-31 22:58:15 +0000
@@ -3,7 +3,7 @@
have ssh && {
_ssh()
{
- local cur prev
+ local cur optconfigfile prev
local -a config
COMPREPLY=()
@@ -11,6 +11,9 @@
prev=${COMP_WORDS[COMP_CWORD-1]}
case "$prev" in
+ -F)
+ _filedir
+ ;;
-*c)
COMPREPLY=( $( compgen -W 'blowfish 3des 3des-cbc blowfish-cbc \
arcfour cast128-cbc' -- $cur ) )
@@ -22,9 +25,24 @@
COMPREPLY=( $( compgen -u -- $cur ) )
;;
*)
- _known_hosts -a
-
- [ $COMP_CWORD -eq 1 ] || \
+ # Search COMP_WORDS for '-F configfile' argument
+ set -- "${COMP_WORDS[@]}"
+ while [ $# -gt 0 ]; do
+ if [ "${1:0:2}" = -F ]; then
+ if [ ${#1} -gt 2 ]; then
+ optconfigfile="$i"
+ else
+ shift
+ optconfigfile="-F$1"
+ fi
+ break
+ fi
+ shift
+ done
+
+ _known_hosts -a $optconfigfile
+
+ [ $COMP_CWORD -eq 1 -o -n "$optconfigfile" ] || \
COMPREPLY=( "${COMPREPLY[@]}" $( compgen -c -- $cur ) )
esac
@@ -36,7 +54,7 @@
#
_scp()
{
- local cur userhost path
+ local cur optconfigfile userhost path
COMPREPLY=()
cur=`_get_cword ":"`
@@ -63,8 +81,23 @@
-e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' ) )
return 0
fi
+
+ # Search COMP_WORDS for '-F configfile' argument
+ set -- "${COMP_WORDS[@]}"
+ while [ $# -gt 0 ]; do
+ if [ "${1:0:2}" = -F ]; then
+ if [ ${#1} -gt 2 ]; then
+ optconfigfile="$i"
+ else
+ shift
+ optconfigfile="-F$1"
+ fi
+ break
+ fi
+ shift
+ done
- [[ "$cur" == */* ]] || _known_hosts -c -a
+ [[ "$cur" == */* ]] || _known_hosts -c -a $optconfigfile
local IFS=$'\t\n'
COMPREPLY=( "${COMPREPLY[@]}" $( command ls -aF1d $cur* \
2>/dev/null | sed \
More information about the Bash-completion-devel
mailing list