Skip to content

Instantly share code, notes, and snippets.

@reski-rukmantiyo
Last active September 17, 2023 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save reski-rukmantiyo/19725dafa64d87dfe1f6f61e13a5244a to your computer and use it in GitHub Desktop.
Save reski-rukmantiyo/19725dafa64d87dfe1f6f61e13a5244a to your computer and use it in GitHub Desktop.
SSH Manager for MacOS / zsh
#!/usr/bin/env zsh
set +H
CONNECTION_FILE="$HOME/.ssh_connections"
# Function to show help menu
show_help() {
echo "SSH Connection Manager"
echo "Usage: ./ssh_manager.sh [OPTION] [ARGS]"
echo
echo "Options:"
echo " add Add new connection."
echo " list List saved connections."
echo " connect Connect using saved preferences."
echo " update Update an existing connection based on its line number."
echo " help Show this help message."
}
# Function to update an existing connection
update_connection() {
line_number=$1
old_connection_info=$(sed "${line_number}q;d" $CONNECTION_FILE)
echo "Old Connection Info: $old_connection_info"
echo -n "Update Nickname (Leave empty to keep, Max 30 characters): "
read nickname
echo -n "Update Host (Leave empty to keep): "
read host
echo -n "Update User (Leave empty to keep): "
read user
echo -n "Update Port [22] (Leave empty to keep): "
read port
echo -n "Update Password or Key [password/key] (Leave empty to keep): "
read auth_type
# Use existing values if no input is provided
host=${host:-$(echo $old_connection_info | awk '{print $1}')}
user=${user:-$(echo $old_connection_info | awk '{print $2}')}
port=${port:-$(echo $old_connection_info | awk '{print $3}')}
auth_type=${auth_type:-$(echo $old_connection_info | awk '{print $4}')}
nickname=${nickname:-$(echo $old_connection_info | awk '{print $1}')}
# Validate the nickname
if [[ "$nickname" =~ \ || ${#nickname} -gt 30 ]]; then
echo "Invalid nickname. No spaces allowed and max length is 30."
return
fi
new_connection_info="$nickname $host $user $port $auth_type $auth_data"
if [[ "$auth_type" == "key" ]]; then
echo -n "Update Private Key Path (Leave empty to keep): "
read key_path
key_path=${key_path:-$(echo $old_connection_info | awk '{print $5}')}
new_connection_info="$new_connection_info $key_path"
elif [[ "$auth_type" == "password" ]]; then
echo -n "Update Password (Leave empty to keep): "
read -s password
password=${password:-$(echo $old_connection_info | awk '{print $5}')}
new_connection_info="$new_connection_info $password"
else
echo "Invalid auth type. Use 'password' or 'key'."
return
fi
# Only update the file if there are changes
if [[ "$old_connection_info" != "$new_connection_info" ]]; then
sed -i "${line_number}s/.*/$new_connection_info/" $CONNECTION_FILE
echo "Connection updated."
else
echo "No changes detected. Nothing to update."
fi
}
# Function to add new connection
add_connection() {
while [[ -z "$nickname" || "$nickname" =~ \ || ${#nickname} -gt 30 ]]; do
echo -n "Nickname (No spaces, Max 30 chars): "
read nickname
done
while [[ -z "$host" ]]; do
echo -n "Host: "
read host
done
while [[ -z "$user" ]]; do
echo -n "User: "
read user
done
while [[ ! "$port" =~ ^[0-9]+$ ]]; do
echo -n "Port [22]: "
read port
port=${port:-22} # Set default port if empty
done
while [[ "$auth_type" != "password" && "$auth_type" != "key" ]]; do
echo -n "Password or Key [password/key]: "
read auth_type
done
if [[ "$auth_type" == "key" ]]; then
while [[ -z "$key_path" ]]; do
echo -n "Private Key Path: "
read key_path
done
echo "$host $user $port key $key_path" >> $CONNECTION_FILE
elif [[ "$auth_type" == "password" ]]; then
while [[ -z "$password" ]]; do
echo -n "Password: "
read -s password
done
echo "$nickname $host $user $port $auth_type $password" >> $CONNECTION_FILE
else
echo "Invalid auth type. Use 'password' or 'key'."
return
fi
}
# Function to list saved connections
list_connections() {
cat $CONNECTION_FILE
}
# Function to connect
connect_ssh() {
identifier=$1
if [[ "$identifier" =~ ^[0-9]+$ ]]; then
connection_info=$(sed "${identifier}q;d" $CONNECTION_FILE)
else
connection_info=$(grep "^$identifier " $CONNECTION_FILE)
fi
if [[ -z "$connection_info" ]]; then
echo "No connection found for identifier $identifier."
return
fi
nickname=$(echo $connection_info | awk '{print $1}')
host=$(echo $connection_info | awk '{print $2}')
user=$(echo $connection_info | awk '{print $3}')
port=$(echo $connection_info | awk '{print $4}')
auth_type=$(echo $connection_info | awk '{print $5}')
auth_data=$(echo $connection_info | awk '{print $6}')
echo "Connecting to $nickname ($user@$host:$port) using $auth_type..."
if [[ "$auth_type" == "key" ]]; then
key_path=$(echo $connection_info | awk '{print $6}')
ssh -o StrictHostKeyChecking=no -i $key_path $user@$host -p $port
elif [[ "$auth_type" == "password" ]]; then
export SSHPASS="$auth_data"
sshpass -e ssh -o StrictHostKeyChecking=no $user@$host -p $port
unset SSHPASS
else
echo "Invalid auth type. Use 'password' or 'key'."
return
fi
}
# Main Script Logic
if [[ ! -f $CONNECTION_FILE ]]; then
touch $CONNECTION_FILE
fi
command=$1
case $command in
add)
add_connection
;;
list)
list_connections
;;
connect)
if [[ -n "$2" ]]; then # Check if identifier is provided
connect_ssh $2
else
echo -n "Enter the nickname or line number to connect: "
read identifier
if [[ -z "$identifier" ]]; then
echo "A nickname or line number is required to connect."
exit 1
fi
connect_ssh $identifier
fi
;;
update)
echo -n "Enter the line number to update: "
read line_number
if [[ -z "$line_number" ]]; then
echo "A line number is required to update a connection."
exit 1
fi
update_connection $line_number
;;
help|*)
show_help
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment