Всем привет! По работе у меня есть потребность постоянно подключаться к разным серверам по ssh, а так же иметь доступ к их файловой системе через sftp. Ранее, у меня было так:
tree -a
.
├── DS
│ ├── SFTP
│ │ ├── DS ARMEN.sh
│ │ ├── DS Asterisk.sh
│ │ ├── DS DEV 158.sh
│ │ ├── DS DEV GOG.sh
│ │ ├── DS Mail.sh
│ │ ├── DS MSK Master.sh
│ │ ├── DS MSK Slave.sh
│ │ ├── DS Net.sh
│ │ ├── DS SPB Master.sh
│ │ ├── DS SPB Slave.sh
│ │ ├── DS LAB.sh
│ │ ├── DS маркетинг.sh
│ │ ├── DS сайта.sh
│ │ └── DS сайт старый.sh
│ └── SSH
│ ├── 158.sh
│ ├── DS Armen.sh
│ ├── DS Asterisk.sh
│ ├── DS DEV 158.sh
│ ├── DS DEV GOG.sh
│ ├── DS Mail.sh
│ ├── DS MSK Master.sh
│ ├── DS MSK Slave.sh
│ ├── DS Net.sh
│ ├── DS SPB Master.sh
│ ├── DS SPB Slave.sh
│ ├── DS LAB.sh
│ ├── DS маркетинг.sh
│ ├── DS Сайт.sh
│ └── DS сайт старый.sh
├── Мое
│ ├── SFTP
│ │ ├── London.sh
│ │ ├── Magnolica.sh
│ │ ├── YADEV.sh
│ │ └── yourpin.sh
│ └── SSH
│ ├── London.sh
│ ├── Magnolica.sh
│ ├── YADEV.sh
│ └── yourpin.sh
└── Разное
├── sftp
│ └── FSBK.sh
└── SSH
├── FSBK.sh
└── wiz.sh
9 directories, 40 files
DS, Мое и Разное это условные названия проектов, над которыми я работаю. Внутри идут папки SFTP и SSH, а в них лежат файлы, которые содержат всего одну строку — подключение к тому или иному серверу. На протяжении нескольких лет меня это вполне устраивало, за исключением обилия телодвижений. Такое количество файлов и папок притормаживает работу, т.к. с замедлен ввод без использования мыши. Можно было бы конечно прописать алиасы подключений в .ssh/config, но масштабно это бы ничего не изменило.
Плодить большое количество файлов на самом деле нет никакого смысла. Изначально я хотел просто при запуске моих sh файл дописать еще пару строк, чтобы дать выбор «Запускаем ssh или sftp?». На этом моменте уже можно было бы остановиться, сократив количество файлов в 2 раза. Но это всё равно не то.
Поэтому, давайте, напишем единый файл, в котором в едином месте прописаны все конфиги подключений, попутно добавим возможность отключения sftp-диска, а так же уйдем от необходимости выбора проекта. Для монтирования и размонтирования дисков будем использовать gio. И вот что получается:
#!/bin/bash
# Настройки подключений.
connections=("Сервер 1|your_host1|your_port1|your_username"
"Сервер 2|your_host2|your_port2|your_username"
"Сервер 3|your_host3|your_port3|your_username")
# Монтирование SFTP диска
mount_sftp() {
server="$1"
IFS='|' read -ra params <<< "$server"
username="${params[3]}"
host="${params[1]}"
port="${params[2]}"
gio mount "sftp://$username@$host:$port/"
}
# Подключение к серверу по SSH
open_ssh_session() {
server="$1"
IFS='|' read -ra params <<< "$server"
username="${params[3]}"
host="${params[1]}"
port="${params[2]}"
ssh_command="ssh $username@$host -p $port"
x-terminal-emulator -e $ssh_command
}
# Выбор действия (Главное меню)
select_action() {
echo "Выберите действие:"
echo "1. Смонтировать SFTP-диск"
echo "2. Открыть SSH-сессию"
echo "3. Отключить SFTP-диск"
read -p "Введите номер действия: " action
case $action in
1)
select_sftp_server
;;
2)
select_ssh_server
;;
3)
unmount_sftp
;;
*)
echo "Неверный выбор. Попробуйте снова."
select_action
;;
esac
}
# Выбор SFTP-сервера
select_sftp_server() {
echo "Выберите SFTP-сервер:"
for i in "${!connections[@]}"; do
IFS='|' read -ra params <<< "${connections[i]}"
echo "$((i+1)). ${params[0]}"
done
read -p "Введите номер SFTP-сервера: " choice
index=$((choice-1))
if [ "${connections[index]}" ]; then
mount_sftp "${connections[index]}"
else
echo "Неверный выбор. Попробуйте снова."
select_sftp_server
fi
}
# Выбор SSH-сервера
select_ssh_server() {
echo "Выберите SSH-сервер:"
for i in "${!connections[@]}"; do
IFS='|' read -ra params <<< "${connections[i]}"
echo "$((i+1)). ${params[0]}"
done
read -p "Введите номер SSH-сервера: " choice
index=$((choice-1))
if [ "${connections[index]}" ]; then
open_ssh_session "${connections[index]}"
else
echo "Неверный выбор. Попробуйте снова."
select_ssh_server
fi
}
# Отключение (отмонтирование) SFTP-диска
unmount_sftp() {
echo "Выберите SFTP-диск для отключения:"
mounted_dirs=($(gio mount -l | grep 'sftp://' | cut -d" " -f6))
for i in "${!mounted_dirs[@]}"; do
IFS='|' read -ra params <<< "${connections[i]}"
echo "$((i+1)). ${mounted_dirs[i]}"
done
read -p "Введите номер SFTP-диска для отключения: " choice
index=$((choice-1))
if [ "${mounted_dirs[index]}" ]; then
gio mount -u "${mounted_dirs[index]}"
else
echo "Неверный выбор. Попробуйте снова."
unmount_sftp
fi
}
# Запуск главного меню
select_action
Данное решение было написано на коленке за 20-30 минут, и оно далеко от идеала. Этот пример кода раскрывает только мои специфические нужды. Вам может показаться это решение в корне неудобным, а код не оптимизированным. В общем строго не судить, это заметка мне на память.
P.S. Наверное, было бы вообще замечательно добавить такую программу в трей и запускать оттуда, но в данный момент она висит на комбинации клавиш и мне вполне комфортно.