Python копирование файлов по ssh
Хочу рассказать про paramiko — модуль для работы с ssh в python.
С его помощью можно написать скрипт, который получит доступ к удаленному серверу (или многим) и что-то на нем сделает.
Поначалу самые простые задачи можно было решить стандартными средствами ssh — копированием файла и удаленным исполнением кода. Также пробовали использовать утилиту empty .
Я в то время как раз начинал учить python, решил посмотреть, что в нем есть для этих целей. Гугл услужливо подсказал про paramiko.
Paramiko (комбинация слов языка есперанто „параноик“ и „друг“ — »paranoja" + «amiko») — это модуль для python версии 2.3 и выше, который реализует ssh2 протокол для защищенного (с шифрованием и аутентификацией) соединения с удаленным компьютером. При подключении предоставляется высокоуровневое API для работы с ssh — создается обьект SSHClient. Для большего контроля можно передать сокет (или подобный обьект) классу Transport и работать с удаленным хостом в качестве сервера или клиента. Клиенту для аутентификации можно использовать пароль или приватный ключ и проверку ключа сервера.
Небольшой пример использования этого модуля. Комментарии будут ниже.
Получить данные для доступа к удаленному серверу можно любым удобным способом — прописать напрямую в коде, вынести в конфиг, базу данных и т.д. Очевидно, что если хостов несколько, то для их обхода нужно делать цикл.
Основным классом для подключения и удаленной работы является SSHClient. Он предоставляет нам «сессию» с которой мы можем работать далее.
В строчке client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) мы добавляем ключ сервера в список известных хостов — файл .ssh/known_hosts. Если при соединении с сервером ключа в нем не найдено, то по умолчанию ключ «отбивается» и вызввается SSHException.
Для соединения с сервером используем client.connect(). Авторизироваться можно как по комбинации логин-пароль так и по ключам. При соединении можно задать хост, имя пользователя, пароль, порт, ключ, и прочие параметры.
Строка client.exec_command('ls -l') — выполняет команду на удаленном сервере. Потоки ввода-вывода программы возврашщаются в файлообразные обьекты — stdin, stdout, stderr.
Возможно, я недоразобрался, но у меня не получилось получить права рута на уделенном сервере. Буду благодарен, если мне подскажут, как это сделать. Для выполнения действий с правами суперпользователя делал так:
UPD: meph1st0 в комментариях предложил для этих целей воспользоваться классом Channel
Для передачи файлов по sftp можно использовать класс Transport. Для непосредственной передачи файлов используются команды put и get.
UPD. В комметариях подсказали, что есть ряд других библиотек инструментов, которые также можно использовать для работы по ssh решения подобных задач. Из перечисленного: fabric, chef, puppet, libbsh2 (pylibbsh2), exscript и net-ssh-telnet на руби. Всем комментаторам спасибо.
I have a text file on my local machine that is generated by a daily Python script run in cron.
I would like to add a bit of code to have that file sent securely to my server over SSH.
The 'executing a command remotely' problem
Now of course we might want to execute this command remotely on another system. For this we can use the same function runCmd(..) in exactly the same way but we need to specify a fabric connection object first. This can be done like this:
Everything remains exactly the same, but this time we run this command on another host. This is intended: I wanted to have a uniform API where there are no modifications required in the software if you at some time decide to move from the local host to another host.
14 Answers 14
To do this in Python (i.e. not wrapping scp through subprocess.Popen or similar) with the Paramiko library, you would do something like this:
(You would probably want to deal with unknown hosts, errors, creating any directories necessary, and so on).
paramiko has a nice sftp.put(self, localpath, remotepath, callback=None) function too, so you don't have to open write, and close each file.
Note: to make this work out of the box add ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) after instantiating ssh .
You need to generate (on the source machine) and install (on the destination machine) an ssh key beforehand so that the scp automatically gets authenticated with your public ssh key (in other words, so your script doesn't ask for a password).
adding ssh key is not a good solution when it is not needed. For example, if you need a one time communication, you don't set up ssh key due to security reasons.
You'd probably use the subprocess module. Something like this:
Where destination is probably of the form user@remotehost:remotepath . Thanks to @Charles Duffy for pointing out the weakness in my original answer, which used a single string argument to specify the scp operation shell=True - that wouldn't handle whitespace in paths.
Ensure that you've set up proper credentials so that you can perform an unattended, passwordless scp between the machines. There is a stackoverflow question for this already.
Using subprocess.Popen is the Right Thing. Passing it a string rather than an array (and using shell=True) is the Wrong Thing, as it means filenames with spaces don't work correctly.
@J.F.Sebastian: yep, I checked it out in December. My upvotes prove that, at least. :) Thanks for the follow-up though.
There are a couple of different ways to approach the problem:
- Wrap command-line programs
- use a Python library that provides SSH capabilities (eg - Paramiko or Twisted Conch)
Each approach has its own quirks. You will need to setup SSH keys to enable password-less logins if you are wrapping system commands like "ssh", "scp" or "rsync." You can embed a password in a script using Paramiko or some other library, but you might find the lack of documentation frustrating, especially if you are not familiar with the basics of the SSH connection (eg - key exchanges, agents, etc). It probably goes without saying that SSH keys are almost always a better idea than passwords for this sort of stuff.
NOTE: its hard to beat rsync if you plan on transferring files via SSH, especially if the alternative is plain old scp.
I've used Paramiko with an eye towards replacing system calls but found myself drawn back to the wrapped commands due to their ease of use and immediate familiarity. You might be different. I gave Conch the once-over some time ago but it didn't appeal to me.
If opting for the system-call path, Python offers an array of options such as os.system or the commands/subprocess modules. I'd go with the subprocess module if using version 2.4+.
I'm writing a script to automate some command line commands in Python. At the moment, I'm doing calls like this:
However, I need to run some commands on a remote machine. Manually, I would log in using ssh and then run the commands. How would I automate this in Python? I need to log in with a (known) password to the remote machine, so I can't just use cmd = ssh user@remotehost , I'm wondering if there's a module I should be using?
The 'executing a command locally' problem
My python module jk_simpleexec provides a function named runCmd(..) that can execute a shell (!) command locally or remotely. This is very simple. Here is an example for local execution of a command:
NOTE: Be aware that the returned data is trimmed automatically by default to remove excessive empty lines from STDOUT and STDERR. (Of course this behavior can be deactivated, but for the purpose you've in mind exactly that behavior is what you will want.)
The 'processing the result' problem
What you will receive is an object that contains the return code, STDOUT and STDERR. Therefore it's very easy to process the result.
And this is what you want to do as the command you execute might exist and is launched but might fail in doing what it is intended to do. In the most simple case where you're not interested in STDOUT and STDERR your code will likely look something like this:
For debugging purposes you want to output the result to STDOUT at some time, so for this you can do just this:
If you would want to process STDOUT it's simple as well. Example:
The password input problem
Now of course there is the password problem. This has been mentioned above by some users: We might want to ask the user executing this python code for a password.
For this problem I have created an own module quite some time ago. jk_pwdinput . The difference to regular password input is that jk_pwdinput will output some stars instead of just printing nothing. So for every password character you type you will see a star. This way it's more easy for you to enter a password.
Here is the code:
(For completeness: If readpwd(..) returned None the user canceled the password input with Ctrl+C. In a real world scenario you might want to act on this appropriately.)
Full example
Here is a full example:
16 Answers 16
I will refer you to paramiko
If you are using ssh keys, do:
@R-Dit, for ssh keys, try getting rid of the password parameter and run the following command before connecting: ssh.load_system_host_keys() .
As a long-time user of Paramiko (but not an expert), I can suggest using Paramiko but you should consider your use cases and how much you're willing to learn. Paramiko is very low-level, and you can easily fall into a trap where you create a "command running helper function" without fully understanding the code you're using. That means you might design say a def run_cmd(host, cmd): which does what you want at first, but your needs evolve. You end up changing the helper for the new use case, which changes behavior of the older existing usage. Plan accordingly.
I used it extensively and it works great.
+1 for a nice simple built-in method. In my current setup I do not want to be adding Python libraries so your suggestion is valuable, very straightforward too.
just make sure your remote host is setup for passwordless ssh, if not, you have to do other things for managing authentication
Keep it simple. No libraries required.
Subprocess is your swiss army knife in automation. You can then combine Python with endless possibilities like shell scripts, sed, awk, grep. Yes you can all do in Python, but wouldnt it be great to just run a grep somewhere in python - well you can.
@BeingSuman You can use SSH key authentication for that. Though I guess You already have figured that out.
I found paramiko to be a bit too low-level, and Fabric not especially well-suited to being used as a library, so I put together my own library called spur that uses paramiko to implement a slightly nicer interface:
If you need to run inside a shell:
I decided to try spur . You generate additional shell commands and you end up with: which 'mkdir' > /dev/null 2>&1 ; echo $?; exec 'mkdir' '-p' '/data/rpmupdate/20130207142923'. I would like to have also access to a plain exec_command . Also missing ability to run background tasks: nohup ./bin/rpmbuildpackages < /dev/null >& /dev/null & . E.g., I generate a zsh script (rpmbuildpackages) using template and then I just to leave it running on the machine. Maybe ability to monitor such background jobs also would be nice (saving PIDs in some ~/.spur).
spur apparently only works on unix systems cause it has a dependency on termios . Does anybody know a good library for Windows?
Not entirely true: if you use a precompiled installer, you will be able to install paramiko and spur. I just did it myself.
@Gabriel: one of the recent releases should have improved support on Windows. If it's still not working, please feel free to open an issue.
@davidlt: when constructing an SshShell , there is now the option to set the shell type. If a minimal shell is used by passing in shell_type=spur.ssh.ShellTypes.minimal , then only the raw command is sent. Implementing background tasks directly feels a bit out of scope for Spur, but you should be able to run the command you've described by invoking a shell e.g. shell.run(["sh", "-c", "nohup ./bin/rpmbuildpackages < /dev/null >& /dev/null &"] ).
All have already stated (recommended) using paramiko and I am just sharing a python code (API one may say) that will allow you to execute multiple commands in one go.
You will see one TODO, which I have kept to stop the execution if any of the commands fails to execute, I don't know how to do it. please share your knowledge
Just use multiprocessing and kill the process if it takes too much time. On the other side it's a problem though, you could put a timeout there too I guess?
paramiko finally worked for me after adding additional line, which is really important one (line 3):
Make sure that paramiko package is installed. Original source of the solution: Source
I have used paramiko a bunch (nice) and pxssh (also nice). I would recommend either. They work a little differently but have a relatively large overlap in usage.
The accepted answer didn't work for me, here's what I used instead:
Alternatively, you can use sshpass:
- Just make sure to connect manually at least one time to the remote system via ssh ( ssh root@ip ) and accept the public key, this is many times the reason from not being able connect using paramiko or other automated ssh scripts.
First: I'm surprised that no one has mentioned fabric yet.
Second: For exactly those requirements you describe I've implemented an own python module named jk_simpleexec . It's purpose: Making running commands easy.
Let me explain a little bit about it for you.
Final notes
So we have the full set:
- Executing a command,
- executing that command remotely via the same API,
- creating the connection in an easy and secure way with password input.
The code above solves the problem quite well for me (and hopefully for you as well). And everything is open source: Fabric is BSD-2-Clause, and my own modules are provided under Apache-2.
В работе Python приложения встала задача получать данные с сетевого оборудования и проводить его настройки удалённо, по SSH. Можно воспользоваться Paramiko, а можно не выдумывать велосипед и использовать основанную на нём библиотеку Exscript. Под катом — примеры кода для подключения и получения информации из команд. Ввиду отсутствия документации к Exscript этот материал может кому-нибудь здорово пригодиться.
Для начала импортируем библиотеку (если нет в системе — скачать можно на гите)
Для Cisco, например, попингуем Гугл, но ничто не мешает использовать команды для конфигурирования:
Именно на Huawei возникла задача, с которой долго боролся — нежелание Exscript ждать выполнения операции, требующей времени и отправки подтверждения. Например, при диагностике пар в линии нужно было подтвердить прерывание сервиса for a while нажатием на y и подтверждением по Enter, а потом подождать пару секунд, пока завершится тест. На этом Exscript вешался, методом проб и ошибок вывел решение.
Пример работы в консоли при ручном подключении к коммутатору для выполнения данной задачи:
sys
Enter system view, return user view with Ctrl+Z.
[SW]int g0/0/5
[SW-GigabitEthernet0/0/5]v
Warning: The command will stop service for a while, continue?[Y/N]:y
Pair A length: 56meter(s)
Pair B length: 56meter(s)
Pair C length: 56meter(s)
Pair D length: 56meter(s)
Pair A state: Open
Pair B state: Open
Pair C state: Open
Pair D state: Open
[SW-GigabitEthernet0/0/5]
А вот так можно сделать в Exscript, ограничивая случайный тест на аплинках через вычет в Description триггера запрета To_Smth_Important_Device:
/N]:Y
Info: This operation may take a few seconds. Please wait for a moment. done.
Pair A length: 56meter(s)
Pair B length: 56meter(s)
Pair C length: 56meter(s)
Pair D length: 56meter(s)
Pair A state: Open
Pair B state: Open
Pair C state: Open
Pair D state: Open
Это статья-мануал по скрипту резервного копирования, написанному мной. Скрипт написан на python для Linux. Кому интересно прошу под хабракат.
Возможности
- Создание дифференциальных/полных копий папок
- Создание дифференциальных/полных копий с файловой системы BTRFS
- Создание дифференциальных/полных копий LVM томов
- Создание снапшотов BTRFS
- Ротирование бэкапов/снапшотов
- Логгирование хода выполнения резервного копирования
- Отправка email оповещений
- Выполнение скриптов до/после резервного копирования
Установка
В /etc/apt/source.list добавить:
И выполнить в терминале:
Обновление пакета выполняется командой:
ИЛИ
Вручную скачать пакет командой:
и установить его:
ИЛИ
Для дистрибутивов, отличных от Ubuntu/Debian выполнить:
И скопировать файлы ddd и py4backup в директорию с бинарными файлами (обычно /usr/bin), файл py4backup_lib.py в директорию библиотек python. Также потребуется поставить зависимости вручную. Необходим python 3.x, btrfs-tools (btrfs-progs), lvm2, rsync. В папке examples/ вы найдете примеры конфигурационных файлов. Их необходимо скопировать в /etc/py4backup/
Настройка
После установки необходимо скопировать конфигурационные файлы из примера. Для этого выполните:
И откройте файл py4backup.conf на редактирование текстовым редактором.
Для boolean параметров допустимо использование True/False, yes/no или 1/0.
Отделять параметр от его значения можно символами '=' или ':'.
Каждый параметр должен находится в своей секции. Название секции пишется перед набором параметров в квадратных скобках ('[]')
Порядок следования параметров в секции и секций не важен. Если параметр не указан в конфигурационном файле, то используется стандартное значение.
Пример конфигурационного файла:
Рассмотрим параметры подробней:
[MAIL]: здесь определяются параметры отправки уведомлений через email.
send_mail_reports: включает/выключает отправку email отчетов после выполнения задания.
login: логин для входа на smtp сервер.
passwd: пароль для входа на smtp сервер.
sendto: получатели уведомления. Можно вписать несколько адресов через пробел.
server: доменное имя или IP адрес smtp сервера.
port: порт smtp сервера.
tls: включает/выключает использование TLS шифрования.
[DD]: здесь указываются параметры создания резервных копий с помощью программ DD и DDD.
bs: размер блока для программы DD (Используется для создания полных копий LVM томов). Можно указывать размер в байтах, килобайтах (k) и мегабайтах (M). Влияет на скорость создания копии. Оптимальное значение- 32M.
ddd_bs: размер блока для программы DDD (Используется для создания дифференциальных копий LVM томов). Можно указывать размер в байтах. Чем больше размер, тем больше места занимает дифференциальная копия, но тем быстрее она создается. Оптимальное значение- 4096.
ddd_hash: алгоритм хеширования блоков. Возможен выбор между md5, crc32 и None. MD5 сильнее нагружает процессор, чем crc32 и занимает больше места, но в случае использования md5 намного меньше шанс коллизий.
None выключает создание чек сумм. Время создания резервной копии, ее размер и нагрузка на процессор минимальны, но в случае повреждения резервной копии вы не будете знать об этом. Не рекомендуется к использованию.
[LOGGING]: настройка ведения журнала заданий.
logpath: путь до журнала. Если вы используете не стандартное размещение журнала не забудьте поменять настройки logrotate.
enable_logging: включает/выключает ведение журнала.
log_with_time: включает/выключает добавление к каждой записи журнала даты и времени.
traceback: включает/выключает добавление traceback'ов в лог при ошибках. Полезно при отладке.
command_output: включает/выключает добавление в лог консольного вывода команд. Полезно при отладке.
[OTHER]: настройки, не вошедшие в другие разделы.
temp_snap_name: имя временных снапшотов. Используется при создании копии LVM томов или папок/файлов на файловой системе BTRFS. Рекомендуется не изменять без необходимости.
host_desc: текстовое описание хоста. Значение этого параметра будет добавлено в файл журнала и email отчет.
pathenv: значение этого параметра будет добавлено к переменной $PATH(если пройдет проверку). Если необходимо добавить несколько папок их необходимо разделить двоеточием (':') Например в Ubuntu для создания копий LVM томов при запуске py4backup через cron необходимо добавить в переменную $PATH папку /sbin. В данном случае путь указывается без последнего слеша (‘/’)
Задания
Общие сведения
Список заданий находится в файле /etc/py4backup/jobs.conf
Пример задания:
Где:
[xxx]: уникальное имя задания.
type: тип задания. Подробности см ниже.
sopath: источник резервной копии. В типах file-full, file-diff в качестве источника можно указывать удаленные хосты.
snpath: где создать снапшот. Используется только типами btrfs-full, btrfs-diff и btrfs-snap
dpath: куда сохранять резервную копию. В типах btrfs-full, btrfs-diff, file-full, file-diff в качестве назначения можно указывать удаленные хосты.
dayexp: через сколько дней удалять старые резервные копии. Если установить -1 резервные копии не будут удаляться никогда.
prescript: скрипт, выполняющийся перед резервным копированием. Пайпы, конвейер и другие операторы bash не работают. Если требуется выполнять сложные команды сохраняйте их виде скрипта и запускайте его.
postscript: скрипт, выполняющийся после резервного копирования. Остальное аналогично параметру prescript.
include: что включать в резервную копию. Подробности см. в описании типов резервного копирования.
exclude: что исключать из резервной копии. Подробности см. в описании типов резервного копирования.
Внимание! Все пути должны заканчиваться '/'.
Типы резервного копирования
- file-full
- file-diff
- btrfs-full
- btrfs-diff
- btrfs-snap
- lvm-full
- lvm-diff
Рассмотрим их поближе.
file-full
Создает резервную копию используя rsync. Создается резервная копия папки, указанной в sopath включая все папки, примонтированные глубже.
Особенности:
В переменной sopath и dpath можно указывать не только локальные папки, но и удаленные хосты. Например:
sopath = root@192.168.0.1:/home/admin/ или dpath = server:/home/admin. Во втором случае в файле ~/.ssh/config должна быть корректная запись. Используется авторизация по ключам (доп. инфо. см. в wiki вашего дистрибутива).
Нельзя указывать sopath и dpath удаленными хостами одновременно.
Значение указанное в include и exclude передаются rsync в виде опций --include= и --exclude=. Можно указывать несколько значений через пробел.
file-diff
Создает дифференциальную резервную копию от источника (sopath) и последней полной копией, найденной в папке назначения (dpath). Если полная копия не будет найдена выполнение задания завершиться ошибкой.
Список параметров аналогичен типу 'file-full'.
btrfs-full
Данный тип аналогичен типу 'file-full', но перед созданием резервной копии делается снапшот резервируемой директории и копия снимается уже со снапшота.
Для этого типа резервного копирования необходимо указание параметра snpath. В папке, указанной в snpath будет создан временный снапшот исходной папки (sopath). Причем указанный там путь должен находится на одной файловой системе с папкой, указанной в sopath. Обратите внимание, что копируется только содержимое данного subvolume файловой системы. Все примонтированные папки и вложенные subvolume будут проигнорированы. Список остальных параметров аналогичен типу 'file-full'.
btrfs-diff
При этом типе рез. копирования сначала с исходной папки (sopath) снимается снапшот, а затем создается дифференциальная копия от снапшота и последней полной копией, найденной в папке назначения (dpath). Если полная копия не будет найдена выполнение задания завершиться ошибкой.
Так же, как и для типа 'btrfs-full' необходимо, что бы папка для снапшота (snpath) находилась на одной файловой системе с исходной папкой (sopath).
Обратите внимание, что копируется только содержимое данного subvolume файловой системы. Все примонтированные папки и вложенные subvolume будут проигнорированы. Список остальных параметров аналогичен типу 'file-full'
btrfs-snap
Данный тип создает снапшоты от исходной папки, указанной в sopath в папку снапшотов, указанную в snpath.
Для данного типа не работают параметры exclude, include, dpath. Так же, как и для типа 'btrfs-full' необходимо, что бы папка для снапшотов (snpath) находилась на одной файловой системе с исходной папкой (sopath).
Обратите внимание, что копируется только содержимое данного subvolume файловой системы. Все примонтированные папки и вложенные subvolume будут проигнорированы.
lvm-full
Этот тип предназначен для создания полных копий LVM томов. Рассмотрим некоторые особенности данного типа. В параметре sopath указывается путь до Logical Volume Group (VG). Например:
sopath = /dev/main_vg/
По умолчанию скрипт сделает копию всех томов, находящихся в данном VG.
Параметр dpath указывает где сохранять резервную копию. Указывать удаленные хосты в качестве назначения резервной копии нельзя. Для того, что бы сделать копии только нужных томов можно использовать параметры include и exclude.
Параметр exclude указывает какие тома исключить из резервной копии. Кроме того он принимает кодовое слово all, обозначающее, что надо исключить все тома.
Параметр include указывает какие тома нужно включить в резервную копию. Имеет приоритет над exclude. Например:
сделает резервную копию только томов mail и root. А следующий пример сделает копию всех томов, кроме тома mail:
lvm-diff
И последний (для версии 1.5) тип резервного копирования предназначен для создания дифференциальных копий LVM томов.
Скрипт ищет в папке назначения (dpath) последнюю полную резервную копию и если находит, создает дифференциальную копию между ней и снапшотом текущего состояния. В папке назначения при этом появятся 2 файла *-diff.dd и *-diff.ddm Они ОБА необходимы для восстановления.
Все параметры аналогичны типу lvm-full
Запуск
Запустить требуемые задания на выполнение очень просто.
Необходимо указать ключ –jobs (или -j) и после него указать имена необходимых заданий. Например:
py4backup --jobs backup_data backup_home backup_media
Все указанные задания выполнятся последовательно в порядке их следования в параметре --jobs. Также запуск скрипта возможен через cron, но помните, что переменное окружен cron может отличатся от пользовательского и может потребоваться указать пути до утилит rm, dd, rsync, btrfs, lvcreate, lvremove в переменной pathenv в конфигурационном файле.
Восстановление
Вот мы и подошли к самому интересному. Резервное копирование само по себе ничего не стоит, без возможности быстро восстановить резервную копию. В данном разделе я опишу типичные кейсы восстановления из резервных копий, созданных скриптом.
Файловые бэкапы
Написанное ниже относится как к полным, так и дифференциальным резервным копиям, сделанным заданиями типа btrfs-full, btrfs-diff, file-full, file-diff. Восстанавливать резервную копию необходимо rsync с ключами -aAX. Например:
В обоих случаях в папке назначения вы получите полную копию данных, готовую к использованию.
Восстановление снапшотов
- Как файловый бэкап, скопировав данные rsync (слишком долго и не интересно)
- Примонтировав снапшот, вместо папки, которую необходимо восстановить. Этот способ мы и рассмотрим ниже.
Таким образом мы во первых сделали наши данные доступными для записи и обезопасили их. Даже когда скрипт согласно ротации удалит снапшот от 2014-06-19 наш свежесозданный снапшот будет цел.
Восстановление полных бэкапов LVM
Тут все совсем просто.
Необходимо создать новый LVM том, размера равного или больше резервной копии и скопировать на него резервную копию с помощью dd.
Пример:
Восстановление дифференциальных бэкапов LVM
Для данного восстановления необходимо воспользоваться утилитой ddd, идущей в комплекте с py4backup.
Для восстановления ей необходимо указать опцию –restore, ключ -s с путем до файла БЕЗ РАСШИРЕНИЯ, ключ -r с указанием места восстановления (блочное устройство или файл). ddd запоминает путь до полной резервной копии, но если она была перемещена необходимо вручную указать ей новый путь. Сделать это можно с помощью ключа -f.
Пример:
В папке /backup находятся резервные копии:
И мы хотим восстановить резервную копию за 2014-06-19 на устройство /dev/main_vg/volume Для этого выполним команду:
Предположим полная копия была перемещена в папку /backup_old/:
После восстановления ddd выведет список поврежденных блоков с указанием файла, где находится поврежденный блок. Запись full23 указывает на повреждение блока номер 23 в файле полной копии, а запись diff24 на повреждение блока 24 в дифференциальной копии.
Tips & Tricks
- Если запустить скрипт без параметров выведется список доступных заданий.
- ddd можно использовать отдельно от py4backup. Путь до полной копии указывается с ключом -f, путь до измененного файла указывается с ключом -s. Ключ -r указывает на место сохранения дифференциальной копии. Пример:
- Если требуется проверить дифференциальную копию, созданную ddd, но не восстанавливать её можно в качестве назначения указать /dev/null
Заключение
Читайте также: