среда, 22 ноября 2023 г.

Автоматическое монтирование USB HDD в выбранную папку.

 Настраивал как-то домашний мини сервер и потребовалось сделать так чтобы при перезагрузке или не дай бог аварийном выключении и включении мини сервера подключенные к нему внешний HDD автоматически примонтировались в нужные папки.

 Решение в лоб с использованием fstab не подошло так как после перезагрузок точка монтирования диска изменялась. Можно было бы воспользоваться UUID но к сожалению и он после перезапусков частенько менялся, что приводило к тому, что необходимо было при старте подключаться к серверу физически и вводить команды вручную для его корректного запуска.

 После этого я подумал использовать crontab ведь в нем есть возможность указать не периодичность с которой нужно выполнять скрипт/команду а указать @reboot и выполнять нужную мне команду после загрузки системы. Однако и здесь  не все так гладно. Это событие срабатывает только при корректном выключении или перезагрузке сервера, а если же было отключение электроэнергии то при запуске после этого скрипт не выполняется.

 Так что остановил свой выбор на rc.local . Однако и тут не все сразу. В Debian 11 по умолчанию нет файла /etc/rc.local и его работу нужно "включить". 


Для этого нужно:

1) Создаем файл /etc/rc.local с содержимым


#!/bin/sh -e sh /root/твой_скрипт.sh exit 0


что-то типа такого: 

пример файла rc.local


2) Делаем файл исполняемым с помощью команды: chmod +x /etc/rc.local

3) Теперь нужно запустить демона rc-local: systemctl start rc-local

4) Ну а теперь проверяем, чтоб работало: systemctl status rc-local

пример вывода когда rc-local запущен


А собственно для подключения внешних HDD я написал пару скриптов 




Вот пример скрипта:

#!/bin/bash
# Попытка сделать скрипт который будет проверять существует ли в системе(подключен) диск
# и если есть, то монтируем его в папку


if [ "$1" = "" ] ; then
    FIRST_SLEEP=60
  else
    FIRST_SLEEP=$1
fi



# Функция для определения есть ли диск в системе
get_hdd_isset() {
  if df | grep -q 'usb-Initio_INIC-3610'; then
    echo "1"
  else
    echo "0"
  fi
}

# Проверяем примонтирована ли эта папка уже
if_hdd_mount() {
  if df | grep -q '/mnt/Storage1/DATA/4TB_1'; then
    echo "1"
  else
    echo "0"
  fi
}

# Получаем адрес диска для монтирования
get_disk() {
  df | grep 'usb-Initio_INIC-3610'|awk '{print $6}'
}


# Переменная для работы с лог файлом
LOG_FILE="/var/log/add_hdd_4TB_1.txt"


# Переменная для индикации подлючен ли диск
HDD_ISSET=$(get_hdd_isset )


# Переменная для счётчика цикла
COUNT=0

sleep "$FIRST_SLEEP"

while [ $COUNT -lt 5 ]; do
  echo "[$(date "+%Y-%m-%d %H:%M:%S")] : Попытка №$((COUNT + 1))" >> "$LOG_FILE"

  if [ "$HDD_ISSET" -eq 1  ]; then
    # истина

    if [ "$(if_hdd_mount)" -eq 1 ]; then
      umount /mnt/Storage1/DATA/4TB_1
      echo "[$(date "+%Y-%m-%d %H:%M:%S")] : диск отмонтирован" >> "$LOG_FILE"
    fi

    TO_MOUNT_DISK=$(get_disk)
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] : Диск в системе присутствует. Будем его монтировать." >> "$LOG_FILE"
    mount --bind "$TO_MOUNT_DISK" /DATA/4TB_1
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] : Диск примонтирован в системе." >> "$LOG_FILE"
    COUNT=99
    continue
  fi


  if [ $COUNT -eq 4 ]; then
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] : Диск в системе не найден. Попытки подключения исчерпаны, завершаем выполнение скрипта." >> "$LOG_FILE"
  else
    echo "[$(date "+%Y-%m-%d %H:%M:%S")] : Диск в системе не найден. Ожидаем 15 секунд и делаем ещё одну попытку." >> "$LOG_FILE"
    sleep 15
  fi


  COUNT=$((COUNT + 1))
done

Скриншот из консоли скрипта монтирования диска