Connecting to EC2 instances using the instance name instead of IP
It's mostly fine, but I would suggest some minor improvements.

Give a proper name to $1 early on, for example:

host=$1
if [ -z $host ]; then
  echo "Please enter machine name"
  return 1
fi


You use it in several places later and it will make the code more readable.



Instead of this:

if [ -z "${instance}" ]; then


you can use [[ ... ]] instead and drop the double quotes:

if [[ -z $instance ]]; then




This is a bit ugly:


ip=$(echo $instance | awk '{print $2}')
pem=$(echo $instance | awk '{print $1}')



It's ugly because you're spawning two awk processes for the same input. You could use a single read instead:

read pem ip junk &lt;&lt;&lt; $instance


Or perhaps slightly cleaner to read into an array:

read -a arr &lt;&lt;&lt; $instance
ip=${arr[1]}
pem=${arr[0]}


The array solution is especially good if the indexes of ip and pem are dynamic, for example if they come from variables:

read -a arr &lt;&lt;&lt; $instance
# given: ip_idx=2 and pem_idx=1
ip=${arr[$ip_idx - 1]}
pem=${arr[$pem_idx - 1]}


(It would be cleaner to have the *_idx 0-based, but I used this example for the sake of illustrating simple arithmetics in array indexes.)

For the record, here's my earlier uglier awk solution:

set -- $(awk '{print $1, $2}' &lt;&lt;&lt; $instance)
pem=$1
ip=$2


This is not as good as read, because it spawns an awk process, and it overwrites the positional parameters $1, $2, ... Other variants using $pem_idx and $ip_idx:

set -- $(awk "{print \$$pem_idx, \$$ip_idx}" &lt;&lt;&lt; $instance)
# or:
set -- $(awk -v ip_idx=$ip_idx -v pem_idx=$pem_idx '{print $(pem_idx), $(ip_idx)}' &lt;&lt;&lt; $instance)




In this code:


local curw
COMPREPLY=()
curw=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=($(compgen -W "${_sash_instances}" -- $curw))



The first COMPREPLY=() is unnecessary because you overwrite it soon after anyway.

Also, I think it's better to write local on the same line as the assignment:

local curw=${COMP_WORDS[COMP_CWORD]}


Actually, since the line fits within 80 characters, I'm not sure I would use the local curw at all:

COMPREPLY=($(compgen -W "${_sash_instances}" -- ${COMP_WORDS[COMP_CWORD]}))




The final return 0 is unnecessary if the last operation is successful. If the last operation is not successful, you probably want to let the function return failure anyway.