Smart I Want

Find the smart technology solutions

How to configure command-line tab completion for known SSH hosts


Configure and enable command-line tab completion for known SSH hosts to ease day-to-day operations from personal notebook. 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 my previus article on how to add SSH menu to Unity launcher.

Ensure that host names and addresses are not hashed for 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 much simpler shell script to take advantege 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 bash-completion repository for more information.



Source link

Please follow and like us:

Related Posts