Configure and enable command-line tab completion for known SSH hosts to ease day-to-day operations. You do need to configure or enable this on Debian-based distributions, but it is good to know how to do this as you will never know when it will come in handy. This article is an extension of adding the SSH menu to the Unity launcher blog post.
Ensure that host names and respective IP addresses are not hashed for the current user from now on.
$ cat << EOF | tee -a ~/.ssh/config Host * HashKnownHosts no EOF
Host * HashKnownHosts no
Create completion configuration for ssh known hosts.
$ cat << EOF | sudo tee /etc/bash_completion.d/ssh_known_hosts_completion # # Bash completion for known SSH hosts # # get user home directory _get_user_home_directory(){ local user_id local user_home_directory user_id=\$(id -u) user_home_directory=\$(getent passwd \${user_id} | cut -d ":" -f 6) echo "\${user_home_directory}" } # determine if known hosts file is hashed is_known_hosts_hashed="" user_home_directory=\$(_get_user_home_directory) for ssh_config_file in "\${user_home_directory}/.ssh/config" "/etc/ssh/ssh_config"; do if [ -f "\${ssh_config_file}" ]; then if [ -z "\${is_known_hosts_hashed}" ]; then is_known_hosts_hashed=\$(awk '/^#/ {next} /HashKnownHosts/ {print \$2}' \${ssh_config_file}) fi fi done # assume that by default known hosts file is not hashed if [ -z "\${is_known_hosts_hashed}" ]; then is_known_hosts_hashed="yes"; fi # generate completion reply with compgen _ssh_known_hosts_completion() { local current_argument local ssh_known_hosts local user_home_directory current_argument=\${COMP_WORDS[COMP_CWORD]}; user_home_directory=\$(_get_user_home_directory) ssh_known_hosts="" if [ -f \${user_home_directory}/.ssh/known_hosts ]; then ssh_known_hosts=\$(awk '/^\|/ {next} {print \$1}' \${user_home_directory}/.ssh/known_hosts | sort | uniq) fi COMPREPLY=(\$(compgen -W '\${ssh_known_hosts}' -- \${currrent_argument})) } # bind completion to ssh command only if known hosts file is not hashed if [ "\${is_known_hosts_hashed}" == "no" ]; then complete -F _ssh_known_hosts_completion ssh fi EOF
# # Bash completion for known SSH hosts # # get user home directory _get_user_home_directory(){ local user_id local user_home_directory user_id=$(id -u) user_home_directory=$(getent passwd ${user_id} | cut -d ":" -f 6) echo "${user_home_directory}" } # determine if known hosts file is hashed is_known_hosts_hashed="" user_home_directory=$(_get_user_home_directory) for ssh_config_file in "${user_home_directory}/.ssh/config" "/etc/ssh/ssh_config"; do if [ -f "${ssh_config_file}" ]; then if [ -z "${is_known_hosts_hashed}" ]; then is_known_hosts_hashed=$(awk '/^#/ {next} /HashKnownHosts/ {print $2}' ${ssh_config_file}) fi fi done # assume that by default known hosts file is not hashed if [ -z "${is_known_hosts_hashed}" ]; then is_known_hosts_hashed="yes"; fi # generate completion reply with compgen _ssh_known_hosts_completion() { local current_argument local ssh_known_hosts local user_home_directory current_argument=${COMP_WORDS[COMP_CWORD]}; user_home_directory=$(_get_user_home_directory) ssh_known_hosts="" if [ -f ${user_home_directory}/.ssh/known_hosts ]; then ssh_known_hosts=$(awk '/^\|/ {next} {print $1}' ${user_home_directory}/.ssh/known_hosts | sort | un iq) fi COMPREPLY=($(compgen -W '${ssh_known_hosts}' -- ${currrent_argument})) } # bind completion to ssh command only if known hosts file is not hashed if [ "${is_known_hosts_hashed}" == "no" ]; then complete -F _ssh_known_hosts_completion ssh fi
You can use a much simpler shell script to take advantage of it on macOS.
$ cat << EOF | tee ~/.bashrc # generate completion reply with compgen for known hosts (ssh) _ssh_known_hosts() { local current_argument; local ssh_known_hosts; current_argument=\${COMP_WORDS[COMP_CWORD]}; ssh_known_hosts=\$(awk '{print \$1}' ~/.ssh/known_hosts | sort | uniq); COMPREPLY=(\$(compgen -W '\${ssh_known_hosts}' -- \$currrent_argument )) } # bind completion to ssh command complete -F _ssh_known_hosts ssh
# generate completion reply with compgen for known hosts (ssh) _ssh_known_hosts() { local current_argument; local ssh_known_hosts; current_argument=${COMP_WORDS[COMP_CWORD]}; ssh_known_hosts=$(awk '{print $1}' ~/.ssh/known_hosts | sort | uniq); COMPREPLY=($(compgen -W '${ssh_known_hosts}' -- $currrent_argument )) } # bind completion to ssh command complete -F _ssh_known_hosts ssh
Inspect a bash-completion repository for more information.