Last active
September 17, 2023 14:14
-
-
Save reski-rukmantiyo/19725dafa64d87dfe1f6f61e13a5244a to your computer and use it in GitHub Desktop.
SSH Manager for MacOS / zsh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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