LINUX.ORG.RU

BASH / Резервное копирование / Циклы

 , , ,


1

1

Всем привет! Появилась задача организовать резервное копирование данных с Windows хостов на сервер с Debian. В написании скриптов полный нуб, слепил из того что было, как смог ))

Принцип работы:

Скрипт запускается по cron'у, пингует хост из списка и если он доступен, то забирает архивы из шары, а на источнике удаляет. Также удаляются архивы старых копий.

Все отрабатывает, кроме случая когда у первого IP по списку шара пустая, прерывается весь цикл. Если у первого по списку файлы есть, а у остальных в разнобой, то все равно работает. Пробовал в функции get_files после else прописать exit, но не катит. Видимо совсем неправильно что-то делаю.

ls: невозможно получить доступ к '/mnt/winhost/*.zip': Нет такого файла или каталога
#!/bin/bash
target_dir='Backup' # Имя шары на удаленном хосте (Н-р: \\Market\Backup)
target_file='*.zip' # Файлы для копирования
mount_dir='/mnt/winhost' # Папка монтирования удаленного хоста
storage_dir='/home/storage' # Хранилище резервных копий
share_login='LOGIN' # Логин для подключения к удаленному хосту
share_pasw='PASSWORD' # Пароль для подключения к удаленному хосту

# Создание папки монтировании, если еще не создана
if [ ! -d $mount_dir ]
  then
    mkdir -p $mount_dir
fi

# Создание папки хранилища, если еще не создана
if [ ! -d $storage_dir ]
  then
    mkdir -p $storage_dir
fi

# Создание папки хоста с именем как IP, если еще не создана
ip_folder () {
	if [ ! -d $storage_dir/$target_host ]
  then
    mkdir -p $storage_dir/$target_host
  fi
	}

# Получение копий с удаленного хоста, 3 варианта
get_files () {
	if ls -d $mount_dir/$target_file
    then
      # mv $mount_dir/$target_file $storage_dir/$target_host
      # cp $mount_dir/$target_file $storage_dir/$target_host
      rsync -urt $mount_dir/$target_file $storage_dir/$target_host
      rm $mount_dir/$target_file
      echo "$(date +"%d-%m-%Y | %H:%M") | $target_host | Файлы скопированы" >> $storage_dir/$target_host/log.txt
    else
      # Записать в лог информацию, если архив не найден
      echo "$(date +"%d-%m-%Y | %H:%M") | $target_host | Файлы не найдены" >> $storage_dir/$target_host/log.txt
  fi
	}

while read target_host
    do

# Пропинговать удаленный хост, выполнить процедуру копирования и записать в лог информацию в случае сбоя
if ping -c1 $target_host >/dev/null 2>&1
  then
      mount -t cifs //$target_host/$target_dir $mount_dir -o username="$share_login",password="$share_pasw"
          ip_folder
          get_files
      umount $mount_dir
        # rm -rf "$mount_dir"
  else
          ip_folder
      echo "$(date +"%d-%m-%Y | %H:%M") | $target_host | Узел недоступен" >> $storage_dir/$target_host/log.txt
fi
            # Удалить файлы старше n-дней
            find /$storage_dir/$target_host -type f -mtime +10 -print0 | xargs -0 rm -f
  done < $storage_dir/iplist.txt

Вижу как минимум отсутствие проверки успешности монтирования и размонтирования.

Держать логины и пароли в скрипте тоже не рекомендую, mount.cifs умеет брать их файла.

Разберись с отступами, самому же читать код легче будет.

Radjah ★★★★★ ()

Замените цикл while на for, примерно так:

for target_host in $(<$storage_dir/iplist.txt); do
  # Пропинговать удаленный хост, выполнить процедуру копирования и записать в лог информацию в случае сбоя
  <...>
done

Мне кажется, что где-то у вас есть команда, пожирающая stdin целиком. Хорошая практика — не использовать while read VAR; do ... done < FILE, когда вы не очень хорошо представляете, что именно запускается в цикле.

Arrest ()
Ответ на: комментарий от Arrest

Мне кажется, что где-то у вас есть команда, пожирающая stdin целиком. Хорошая практика — не использовать while read VAR; do ... done < FILE, когда вы не очень хорошо представляете, что именно запускается в цикле.

О, господи. Это вы сами придумали, а ли подсказал кто?

vodz ★★★★ ()