Сортировка Бекапов

Hollman

Новичок
Пользователь
Июн 13, 2020
4
0
1
Всем привет ,столкнулся с проблемой,скрипт кидает бекапы в нужную мне,только что созданную папку с текущей датой,но помимо нее создает еще 9 папок с именами - ,2 ,3,4 и т.д. Не могу понять где я ошибся.

Код:
import sys
import time
from netmiko import ConnectHandler
import os
import cmd
import datetime
import re
import shutil

now = datetime.datetime.now()
device_params={}
with open('ip2.txt', 'r') as f:
    nums = f.read().splitlines()
    for el in nums:
        if el:
            ip, user, password, enable_password, port, = el.replace(' ', '').split(":")
            device_params = {
                'device_type': 'cisco_ios',
                'ip': ip,
                'username': user,
                'password': password,
                'secret': enable_password,
                'port': port
            }
            print(device_params)
        connection = ConnectHandler(**device_params)
        connection.enable()
        output = connection.send_command('show run')
        prompt = connection.find_prompt()
        hostname = prompt[:-1]
        path = 'C://adb/'
        folder_names = str(now.year) + '-' + str(now.month) + '-' + str(now.day)
        def createFolderForTiff(folder_names, path):
            _fold_name = folder_names
            _path = path

            if (os.path.exists(_path + '/' + _fold_name)):
                print('Папка с именем ' + folder_names + ' уже существует')
            else:
                os.chdir(_path)
                os.mkdir(_fold_name)
        for name in folder_names:
            createFolderForTiff(name, path)

        today = str(now.year) + '-' + str(now.month) + '-' + str(now.day)
        file = today + '-' + hostname + '.txt'

        with open(file, 'w') as backup:
            backup.write(output)
            shutil.copy(file, folder_names)
            print('Backup of ' + hostname + ' completed successfuly')
            print('#' * 30)

        connection.disconnect()
 
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Вот тут вы создаете строку с датой:
Python:
 folder_names = str(now.year) + '-' + str(now.month) + '-' + str(now.day)
Потом проходите по ней в цикле:
Python:
for name in folder_names:
    createFolderForTiff(name, path)
В результате функция createFolderForTiff(name, path) вызывается много раз (для каждого символа из строки с датой) и в качестве аргумента name получает 1 символ из строки с датой. Поэтому создаются папки с именами, состоящими из одной цифры.
 
  • Мне нравится
Реакции: Student и Hollman

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Можно попробовать сделать проверку через try/except и в случае исключения пытаться подключиться по телнету.
Вот пример:
Python:
import sys
import time
from netmiko import ConnectHandler
import os
import cmd
import datetime
import re
import shutil

now = datetime.datetime.now()
device_params={}
with open('ip2.txt', 'r') as f:
    nums = f.read().splitlines()
    for el in nums:
        connection = None
        try:
            if el:
                ip, user, password, enable_password, port, = el.replace(' ', '').split(":")
                device_params = {
                    'device_type': 'cisco_ios',
                    'ip': ip,
                    'username': user,
                    'password': password,
                    'secret': enable_password,
                    'port': port
                }
                print(device_params)
            connection = ConnectHandler(**device_params)
            connection.enable()
        except:
            try:
                if el:
                ip, user, password, enable_password, port, = el.replace(' ', '').split(":")
                device_params = {
                    'device_type': 'cisco_ios_telnet',
                    'ip': ip,
                    'username': user,
                    'password': password,
                    'secret': enable_password,
                    'port': port
                }
                print(device_params)
                connection = ConnectHandler(**device_params)
                connection.enable()
            except Exception as e:
                print(e)
        
        if connection is not None:
            output = connection.send_command('show run')
            prompt = connection.find_prompt()
            hostname = prompt[:-1]
            path = 'C://adb/'
            folder_names = str(now.year) + '-' + str(now.month) + '-' + str(now.day)
            def createFolderForTiff(folder_names, path):
                _fold_name = folder_names
                _path = path

                if (os.path.exists(_path + '/' + _fold_name)):
                    print('Папка с именем ' + folder_names + ' уже существует')
                else:
                    os.chdir(_path)
                    os.mkdir(_fold_name)
            for name in folder_names:
                createFolderForTiff(name, path)

            today = str(now.year) + '-' + str(now.month) + '-' + str(now.day)
            file = today + '-' + hostname + '.txt'

            with open(file, 'w') as backup:
                backup.write(output)
                shutil.copy(file, folder_names)
                print('Backup of ' + hostname + ' completed successfuly')
                print('#' * 30)

            connection.disconnect()
 
  • Мне нравится
Реакции: Hollman

Hollman

Новичок
Пользователь
Июн 13, 2020
4
0
1
Вот тут вы создаете строку с датой:
Python:
 folder_names = str(now.year) + '-' + str(now.month) + '-' + str(now.day)
Потом проходите по ней в цикле:
Python:
for name in folder_names:
    createFolderForTiff(name, path)
В результате функция createFolderForTiff(name, path) вызывается много раз (для каждого символа из строки с датой) и в качестве аргумента name получает 1 символ из строки с датой. Поэтому создаются папки с именами, состоящими из одной цифры.
Спасибо,разобрался.
Если я ещё не утомил ,то можете посоветовать решение,как реализовать чтобы в моем скрипте,при неудачной попытке подключения по ssh,скрипт конектился по telnet?Я знаю что netmiko поддерживает телнет и что достаточно поменять device_type': 'cisco_ios_telnet',но если я просто добавляю строку с изменением словаря,то скрипт все равно останавливается после неудачной попытки подключения по ссш.
 

Hollman

Новичок
Пользователь
Июн 13, 2020
4
0
1
import shutil
from os import listdir
from os.path import isdir, join
from datetime import timedelta, datetime
import os.path

# Директория с бэкапами
directory = r'/C://adb/'

# Время хранения бэкапов в днях
days = timedelta(days=60)

# Получаем содержимое директории
only_directory = [f for f in listdir(directory) if isdir(join(directory, f))]

# Пробегаемся в цикле по директории
for folder in only_directory:
p = [x for x in listdir(directory + folder)]
for path in p:
# Определяем возраст папки
how_long_ago_creation_date = datetime.now()-datetime.fromtimestamp(os.path.getctime(directory+folder+'/'+path))
print(path+" created "+str(how_long_ago_creation_date)+" ago")

# Если дата создания папки больше days то удаляем
if (how_long_ago_creation_date>days):
print("Delete folder: "+directory+folder+'/'+path)

# Исключение так как не всегда удается удалить, папка/файл может быть чем-то занята
try:
shutil.rmtree(os.path.join(os.path.abspath(os.path.dirname(__file__)), directory+folder+'/'+path))
except OSError:
print('Не удалось удалить папку')

Все отлично,я бился над этим неделю))Вероятно я просто неправильно понял как работает except,я пытался подставить в него текст ошибки чтобы по ее появлению срабатывал тригер и выполнялось условие подключения по телнет,но разумеется у меня не сработало.Ваше решение то что нужно!)
Есть еще затык ,хочу добавить в скрипт удаление старых бекапов ,скрипт работает и чистит старые бекапы,но он вычищает все файлы не оставляя ничего если условия выполняются,я хочу добавить какой-нибудь каунтер чтобы скрипт всегда оставлял не менее пяти бекапов,цифра не принципиальна. Я могу это реализовать путем вырезания всех файлов бекапов в папку типа темпа,там отсортировать,оттуда скопировать последние 5-10 бекапов обратно ,а папку темпа со всем содержимым потом грохнуть.Получается как-то громоздко,может есть какая-нибудь библиотека с которой можно просто добавить условие для моего скрипта ,или все же реализовывать то как я написал и это единственный выход?
 
Последнее редактирование:

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Есть еще затык ,хочу добавить в скрипт удаление старых бекапов ,скрипт работает и чистит старые бекапы,но он вычищает все файлы не оставляя ничего если условия выполняются,я хочу добавить какой-нибудь каунтер чтобы скрипт всегда оставлял не менее пяти бекапов,цифра не принципиальна. Я могу это реализовать путем вырезания всех файлов бекапов в папку типа темпа,там отсортировать,оттуда скопировать последние 5-10 бекапов обратно ,а папку темпа со всем содержимым потом грохнуть.Получается как-то громоздко,может есть какая-нибудь библиотека с которой можно просто добавить условие для моего скрипта ,или все же реализовывать то как я написал и это единственный выход?
Вот пример кода, который показывает как сортировать файлы и папки по дате:
Python:
import shutil
import os
from pathlib import Path
from datetime import datetime, timedelta


# Директория с бэкапами
directory = 'C://adb/'

# Время хранения бэкапов в днях
days = timedelta(days=60)

# список путей к файлам и папкам внутри папки с бекапами
# отсортированный по дате создания
paths = sorted(Path(directory).iterdir(), key=os.path.getmtime)

print('-' * 10, 'Все папки', '-' * 10)
# все папки
for folder in paths:
    print(folder)

print('-' * 10, 'Все кроме последних 3х', '-' * 10)
# все папки кроме последних 3х
for old_folder in paths[:-3]:
    #print(old_folder)

    # определяем как давно создана папка
    how_long_ago_creation_date = datetime.now() - datetime.fromtimestamp(os.path.getmtime(old_folder))
    print(str(old_folder) + " created " + str(how_long_ago_creation_date) + " ago")
    # Если дата создания папки больше days то удаляем
    if (how_long_ago_creation_date > days):
        print("Delete folder: " + str(old_folder))
        #удаление (пока закомментировал)
        #try:
        #  shutil.rmtree(old_folder)
        #except OSError:
        #  print('Не удалось удалить папку')
 
  • Мне нравится
Реакции: Hollman

Hollman

Новичок
Пользователь
Июн 13, 2020
4
0
1
Вот пример кода, который показывает как сортировать файлы и папки по дате:
Python:
import shutil
import os
from pathlib import Path
from datetime import datetime, timedelta


# Директория с бэкапами
directory = 'C://adb/'

# Время хранения бэкапов в днях
days = timedelta(days=60)

# список путей к файлам и папкам внутри папки с бекапами
# отсортированный по дате создания
paths = sorted(Path(directory).iterdir(), key=os.path.getmtime)

print('-' * 10, 'Все папки', '-' * 10)
# все папки
for folder in paths:
    print(folder)

print('-' * 10, 'Все кроме последних 3х', '-' * 10)
# все папки кроме последних 3х
for old_folder in paths[:-3]:
    #print(old_folder)

    # определяем как давно создана папка
    how_long_ago_creation_date = datetime.now() - datetime.fromtimestamp(os.path.getmtime(old_folder))
    print(str(old_folder) + " created " + str(how_long_ago_creation_date) + " ago")
    # Если дата создания папки больше days то удаляем
    if (how_long_ago_creation_date > days):
        print("Delete folder: " + str(old_folder))
        #удаление (пока закомментировал)
        #try:
        #  shutil.rmtree(old_folder)
        #except OSError:
        #  print('Не удалось удалить папку')

Спасибо,буду разбираться)
 

Форум IT Специалистов