LINUX.ORG.RU
решено ФорумTalks

Бекапилка вашего ПекА

 , , , ,


2

2
- АХТУНГ, ВАХТУНГ, БАХТУНГ, ДРЯХТУНГ, АЛЯРМ, ВНИМАНИЕ
- ЭТОТ СКРИПТ ПРЕДОСТАВЛЯЕТСЯ КАК ЕСТЬ, Я НЕ НЕСУ НИКАКОЙ
- ОТВЕТСТВЕННОСТИ ЯВНОЙ ИЛИ КОСВЕННОЙ, ВАМ ЛИБО КОМУ ТО ЕЩЁ
- ПО ПРИЧИНЕ, ПОРЧИ И/ИЛИ УНИЧТОЖЕНИИ ВАШИХ ДАННЫХ 
- ЕСЛИ ВЫ НЕСОГЛАСНЫ, Я ЗАПРЕЩАЮ ВАМ ЗАПУСКАТЬ ЭТОТ КОД
- ДЕЙСТВУЙТЕ НА СВОЙ СТРАХ И РИСК, ВАШИ ЛЮБЫЕ СОМНЕНИЯ 
- КАСАТЕЛЬНО СКРИПТА ДОЛЖНЫ ВЕСТИ К ОТКАЗУ ОТ ЕГО ИСПОЛЬЗОВАНИЯ

Всё, теперь если у вас что-то пойдёт не так, то я чист.
И меня никто не будет ругать, гы :) Просто будте внимательный с тем,
какой каталог указывается для сохранения бекапов. А то ведь так и затереть чего важного можно случайно.
Вопщем решил поделится прост. Пусть будет.

Простой скрипт ручного бекапа наиболее важных файлов, использует
rsync и zip Настройка производится внутри стрипта. Описание
настройки бекапа тоже распологается внутри скрипта.
Типичное использование это ручной запуск в конце дня или по
завершению какой либо важной работы или перед сном :)
Используйте для бекапа, отдельный диск где нет ничего кроме бекапа!
Просто иначе, в бекапе нет никакого смысла.
Лично я просто на панельку кнопочку сделал, и перед отплытием в люльку тыкаю кнопочку.
Комп я не выключаю обычно, а если выключаю до явно дожидаюсь окончания бекапа, не проверял что будет если увести в сон во время бекапа, так что, лучше дождаться окончания.

Зависимости

mkdir zip rsync notify-send lua

Использование

Настроить скрипт, после чего просто его запускать. Так как вам удобно.

  • Обязательные параметры
    • source каталог или файл источник
    • dest каталог приёмник
  • Дополнительные параметры
    • secure применить пароль (требуется zip=true)
    • zip сжать в архив
    • mirror сделать точную копию и обновить им текущий каталог бекапа( или архив если zip=true)
    • versions сделать точную копию и пометить датой в отдельном каталоге (или архиве если zip=true)

Пример поля конфигурации:

  • {secure=true, zip=true, versions=true, source='~/.ssh/', dest='ssh'};

Значит что нужно сделать рекурсивный бекап каталога с ключами ssh и расположить бекап в каталоге с именем ssh. secure=true означает что данные будут запаролены, а zip что будут сжаты, versions=true означает что каждый новый бекап будет создавать новую копию ~/.ssh помеченную датой. Описание того какие есть ключи и как они работают друг с другом есть внутри скрипта, вместе с примерами уже готовой настройки.

Ключи можно опускать (не указывать) обязательными являются только source и dest Не указанные ключи считаются заданными как false так что вот такая запись валидна

  • {source='~/Изображения/', dest='картинки'}

И означает сделать копию каталога ~/Изображения в каталоге картинки внутри общего каталога бекапа backup_path=... при этом если это второй или последующий бекап и в каталоге ~/Изображения/ была удалена картинка, она не будет удалена в каталоге картинки это сделано специально, дабы максимизировать сохраняемые данные. Если нужна точная копия с удалением того чего уже нет в каталоге источнике то нужно дополнительно явно указать опцию mirror=true это же правило работает если включить флаг zip=true будет всё тоже самое, но уже в виде архива.

На заметку

В каталоге относительно котрого исполняется скрипт будет лог бекапа, на рабочий стол будут приходить уведомление о текущем статусе выполнения, в случае ошибки будет показaн код возврата В лог попадает информация о том какая именно команда потерпела неудачу, пароль присутцвующий в команде заменяется на звёздочки. В зависимости от типа настроенного бекапа(первый бекап будет всегда долгим), а вот последующие при отсуцтвии изменений будут быстрыми исключение это mirror и versions оба создают точную копию с нуля, а не пытаются обновить текущее содержимое бекапа. В случае если любая программа вернёт код возврата отличный от 0 выполнение всего бекапа прерывается, и повторно он не запустится пока не будет удалён lock файл, это сделано специально, чтобы выяснить причину, исправить её и в ручном режиме удалить lock файл название котрого есть в срипте, в логах и уведомлении на рабочий стол.:

Если вы бекапите например ~./vimrc в dest каталог myvimrc то он будет там лежать как есть, с точкой. Так что так же чтобы его увидеть в каталоге бекапа нужно нажимать ctrl+h. Ну, я так. На всякий случай.

Удалять из бекапов лишнее, и вообще контролировать влезет ли всё, это ваша забота =)
Нет опции отключения уведомлений. Предпочитаю явно знать что всё прошло гладко.
Логи бекапа тоже руками удалять.

Дадада, пароль на zip для ssh и gpg ключей хахахаха, но хоть что-то.
Сам внешний накопитель держите шифрованным если туда важное сохраняется.

Сам сриптик. Взял его как есть.

#!/usr/env lua
local backup_rule =
{
    --каталог куда будут размещаться все бекапы
    backup_path = '/media/$USER/STORAGE_SSD/backup';
    --пароль если используется secure=true, лучше использовать файл с паролем
    backup_pass = nil;
    --пароль для важныйх файлов, можно записать в файл дабы не светить
    backup_pass_file = "/home/$USER/Документы/backup_pass";
    ---------------------------------------------------------------------------
    backup_list =
    {
    -- backup critical --
    {secure=true, zip=true, versions=true, source='~/.ssh/',     dest='ssh'    };
    {secure=true, zip=true, versions=true, source='~/.gnupg/',   dest='gpg'    };
    {secure=true, zip=true, mirror=true,   source='~/.config/',  dest='cfg'    };
    {secure=true, zip=true, mirror=true,   source='~/.mozilla/', dest='firefox'};
    {secure=true, zip=true, mirror=true,   source='~/Документы/',dest='doc'    };

    -- diffrerent media --
    {secure=false,zip=true, mirror=true, source='~/Книги/', dest='book'};
    {secure=false,zip=true, mirror=true, source='~/Музыка/',dest='music'};

    -- backup multimedia --
    {secure=false, zip=false, versions=false, source='~/FAMILY_ARCHIVE/', dest='family'};

    -- backup dev stuff  --
    {secure=false, zip=false, versions=true, source='~/.gitconfig',dest='gitconfig'};
    {secure=false, zip=false, versions=true, source='~/.vimrc',    dest='vimrc'};
    {secure=false, zip=false, versions=true, source='~/.bashrc',   dest='bashrc'};
    {secure=false, zip=true,  versions=true, source='~/.vim/',     dest='vim'};

    -- backups source code --
    {secure=false, zip=true, mirror=true, source='/mnt/STORAGE/', dest='code'};

    };
};
-------------------------------------------------------------------------------
-- :secure=true   - шифровать ли сжатый бекап с паролем.
--                  создать архив и запаролить, zip должен быть zip=true
--                  явное указание zip=false или отсуцтвие ключа создаст ошибку
-- ----------------------------------------------------------------------------
-- :secure=false  - тоже самое поведение что и при zip=false
-- ----------------------------------------------------------------------------
-- :zip=true      - создать архив и добавить в него файлы если их нет в архиве
--                  если version=false то обновлять архив, добавляя новые
--                  файлы и обновля существующие, не удаляет отсуцтвующие
-------------------------------------------------------------------------------
-- :zip=false     - создавать бекап в каталоге dest если versions=false
--                  то клонировать source в dest, при повторном бекапе добавлять
--                  новые файлы и обновлять текущие, не удалять отсуцтвующие
--                  если versions=true создавать отдельный бекап в новом
--                  каталоге с датой бекапа, полностью отельный бекап.
-------------------------------------------------------------------------------
-- :versions=true - если zip=false то создать новый каталог с датой бекапа
--                  если zip=true  то создать новый архив с датой бекапа
-------------------------------------------------------------------------------
-- :mirror=true   - если zip=true то создаётся точная сжатая копия источника
--                  если при этом versions=false то текущий архив удаляет из
--                  себя файлы которых больше нет в источнике
--                  если zip=false то вместо архива создаётся точная копия
--                  источника с удалением файлов из каталога бекапа если их
--                  нет в источнике, тоже самое зеркалирование/клонирование
-------------------------------------------------------------------------------
-- :source        - файл или каталог который нужно бекапить, каталоги
--                  обрабатываются рекурсивно бекапя всё что есть
-------------------------------------------------------------------------------
-- :dest          - каталог внутри носителя для бекапа, оно же префикс
--                  добавляющийся к каталогам и/или архивам при versions=true
--                  отражает то бекап чего делается ОБЯЗАН БЫТЬ УНИКАЛЬНЫМ!!!!
-------------------------------------------------------------------------------
--        Если какого либо ключа нет то он считается равным false
-------------------------------------------------------------------------------
-- В случае если zip mkdir или rsync завершаться с кодом отличным от нуля
-- бекап тут же прекращается с уведомлением на рабочий стол и в лог ошибок
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
---- исполняет все команды, в случае ошибки прерывает всю работу
-------------------------------------------------------------------------------
local function execute(rule,command,exit_if_fail)
    local success, meta, code = os.execute(command..' >> backup-info.log');
    if (not success) then
       -- hide pass from output
       -- info log and messages
       if rule.backup_pass then
          command = command:gsub(rule.backup_pass,"********");
       end
       local msg = string.format('BACKUP ERROR %s %s %s',command,meta,code);
       io.stderr:write(msg..'\n');
       io.open('backup-error.log','a+'):write(msg);
       execute({},'notify-send  "'..msg..'" -u critical',false);
       if (exit_if_fail == true) then
          os.exit(127);
       end
       return success;
    end
    return success;
end
-------------------------------------------------------------------------------
--- информирует об ошибке и прерывает всю работу
-------------------------------------------------------------------------------
local function backup_fail(msg)
      io.stderr:write(msg..'\n');
      io.open('backup-error.log','a+'):write('\n'..msg..'\n');
      execute({},'notify-send -u critical "'..msg..'"',false);
      os.exit(127);
end
-------------------------------------------------------------------------------
--- просто информирует
-------------------------------------------------------------------------------
local function backup_info(msg)
      io.stdout:write(msg..'\n');
      local log = io.open('backup-info.log','a+');
      log:write('\n'..msg..'\n');
      log:close();
      execute({},'notify-send -u normal "'..msg..'"',false);
end
-------------------------------------------------------------------------------
--- проверяет используется ли в конфигурации пароль
-------------------------------------------------------------------------------
function check_need_pass(rule)
    for name,val in pairs(rule.backup_list) do
        if val.secure and val.secure == true then
           return true;
        end
    end
    return false;
end
-------------------------------------------------------------------------------
--- делает бекап K.O. :)
-------------------------------------------------------------------------------
local function make_backup(rule)
    if (rule.backup_path) then
       -- replaice $USER in path if we have ite
       rule.backup_path = rule.backup_path:gsub('$USER',os.getenv('USER'));
    else
       backup_fail('BACKUP ERROR backup_path not set, no place to save backup',true);
    end
    -- we use password?
    if (check_need_pass(rule) == true) then
        -- check pass contained in configuration
        if not rule.backup_pass and not rule.backup_pass_file then
           backup_fail('BACKUP ERROR you use secure option but backup_pass or backup_pass_file no set!',true);
        end
        -- if pass_file set read the password
        -- and override/write rule.backup_pass
        if (rule.backup_pass_file) then
           -- replaice $USER in path if we have ite
           rule.backup_pass_file = rule.backup_pass_file:gsub('$USER',os.getenv('USER'));
           local pass_file = io.open(rule.backup_pass_file);
           if (pass_file) then
              if rule.backup_pass then
                 backup_info('BACKUP WARNING rewrite backup_pass from backup_pass_file');
              end
              rule.backup_pass = pass_file:read('*l');
           else
              backup_fail('BACKUP ERROR '..rule.backup_pass_file..' no readable!',true);
           end
           pass_file:close();
        end
        -- maybe pass use only numbers force to string
        rule.backup_pass = tostring(rule.backup_pass);
        -- check small pass, no need but jut be
        if not rule.backup_pass or #rule.backup_pass <= 4 then -- kek cheburek 
           backup_info('BACKUP WARNING you backup_pass small, less or equal 4 symbols');
        end
    end
    -- info about starting
    backup_info("BACKUP START "..os.date());
    --first check, we have storage and access?
    execute(rule,'mkdir -p '..rule.backup_path, true);
    -- lockfile + uuid for exclude collisions
    local lockfile = '.lock-938448fc-1742-43e9-bff8-e2acf6d29710';
    -- check/create lock file
    -- if backup failed you self
    -- delete lock file your hands
    if not io.open(rule.backup_path..'/'..lockfile,'r') then
       io.open(rule.backup_path..'/'..lockfile,'w'):write('lock');
    else
       backup_fail("OTHER BACKUP PROCESS IS WORKING, SKIPPING THIS PROCESS\n"..
                   "IF YOU SURE DELETE LOCK FILE "..rule.backup_path..'/'..lockfile..'\n',true);
       ----------------------------------------------------------------------
       -- uncomment if after backup error no need locked backup for fix error
       ----------------------------------------------------------------------
       -- os.remove(rule.backup_path..'/'..lockfile);
    end
    for id,item in pairs(rule.backup_list) do
        local date = os.date("%Y-%m-%d_%X");
        local path = rule.backup_path;
        local pass = rule.backup_pass;
        local dest = item.dest;
        local source = item.source;

        if (not source) then
           backup_fail('BACKUP ERROR source path not set, what files backup?',true)
        end

        if (not dest) then
           backup_fail('BACKUP ERROR dest path not set, wheare dir name to save?',true)
        end

        execute(rule,'mkdir -p '..path..'/'..dest,true);
        backup_info('BACKUP: '..source);

        ------------------- secure: versionize backup data ---------------------
        ------------------------------------------------------------------------
        if (item.secure and item.zip and item.versions) then
            local target = string.format('%s/%s/%s-%s.zip',path,dest,dest,date);
            execute(rule,'zip -r9P '..pass..' '..target..' '..source,true);
            goto next_item;
        end
        ---------------- secure: update and append backup data -----------------
        ------------------------------------------------------------------------
        if (item.secure and item.zip and not item.versions) then
            local target = string.format('%s/%s/%s.zip',path,dest,dest);
            local opts = item.mirror and ' -rFS9P ' or ' -ru9P ';
            execute(rule,'zip '..opts..' '..pass..' '..target..' '..source,true);
            goto next_item;
        end
        ----------- no secure: zipped update and append backup data ------------
        ------------------------------------------------------------------------
        if (not item.secure and item.zip and not item.versions) then
           local target = string.format('%s/%s/%s.zip',path,dest,dest);
           local opts = item.mirror and ' -rFS9 ' or ' -ru9 ';
           execute(rule,'zip '..opts..' '..target..' '..source,true);
           goto next_item;
        end
        ----- no secure: zipped, versionize update and append backup data ------
        ------------------------------------------------------------------------
        if (not item.secure and item.zip and item.versions ) then
           local target = string.format('%s/%s/%s-%s.zip',path,dest,dest,date);
           execute(rule,'zip -r9 '..target..' '..source,true);
           goto next_item;
        end
        --------- no secure: versionize update and append, no delete -----------
        ------------------------------------------------------------------------
        if (not item.secure and not item.zip and item.versions ) then
           local target = string.format('%s/%s/%s-%s/',path,dest,dest,date);
           execute(rule,'mkdir -p '..target);
           execute(rule,'rsync -arv '..source..' '..target,true);
           goto next_item;
        end
        ----------------- no secure: update and append, no delete --------------
        ------------------------------------------------------------------------
        if (not item.secure and not item.zip and not item.versions) then
           local target = string.format('%s/%s/',path,dest);
           execute(rule,'mkdir -p '..target);
           local opts = item.mirror and ' -arv --delete ' or ' -arv ';
           execute(rule,'rsync '..opts..' '..source..' '..target,true);
           goto next_item;
        end
        ------------------------------------------------------------------------
        if (item.secure and not item.zip) then
            backup_fail('BACKUP ERROR UNSUPPORT SECURE WITCHOUT ZIP ARCHIVE :(');
        end
        ::next_item::
    end
    backup_info("BACKUP END "..os.date());
    os.remove(rule.backup_path..'/'..lockfile);
end

-- check depends
execute({},"zip --version",true);
execute({},"rsync --version",true);
--execute({},"mkdir --version",true);
execute({},"notify-send --version",true);
-- start backup now
make_backup(backup_rule)

Всё. Досвиданья.

Ответ на: комментарий от sanyo1234

Если подытожить, то нормальный бэкап сервер - это:

  • ZFS on Linux v0.8.6 (минимальный без графической части и чего-либо лишнего Devuan ASCII + немного пакетов типа libc и SSH из Beowulf/Chimaera вообще без всех этих dbus, *kit, etc.) с массивом в пуле из тройных зеркальных vdevs. Libre ядро v4.19.latest
  • Компик на старом Core2 с хорошо проверенной оперативкой или AM3+ типа Phenom2 с небуферизированной ECC оперативкой с доступом только через SSH только с аутентификацией через PKCS11 с кнопкой авторизации на брелоке.
  • Системник размещён в дополнительном заземленном металлическом вентилируемом корпусе. В идеале в подземном бункере :)
  • Надёжное электропитание
  • Для бэкапов подключение наружу через ОПТИКУ к отдельному управляющему бэкапами шлюзу (тоже Core2 или AM3+) с локалкой при полном отключении вычислительного контура с другой стороны шлюза от Internet на время бэкапа. Ессно никаких беспроводных устройств, подключенных к контуру, по крайне мере на время бэкапа (ZFS репликации).
sanyo1234
()
Последнее исправление: sanyo1234 (всего исправлений: 4)
Ответ на: комментарий от cobold

Чтобы можно было самому её взломать, когда забудешь пароль.

rupert ★★★★★
()

Какие цели были при создании этого велосипеда (кроме желания почесать NIH-синдром)?

theNamelessOne ★★★★★
()

Дожились. Скрипты бэкапилок. На ЛОРе. На lua.

Кажется это уже тот ЛОР, который мы заслужили.

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

Ты щёта имеешь сказать супротив луашечки?!!1 Какие ваши доказательства! :D Всё нормально, у тебя графические приложения на PHP, у меня околосистемный софт на Lua.

А так, lua для таких вещей и создан был изначально. Ещё до рождения этих ваших питонов, пхп и прочих многих. Это универсальный повседневный пользовательский язык для любых прикладных задач и расширения любых других программ. Более чем адекватно писать на нём пользовательские пограмульки. А так это вообще просто такой внешний интерфейс для сишечки. Идеааально.

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Скриптота для бэкапа слишком коротка и мала, чтобы для нее надо было подключать еще какой-то язык.

SH хватит каждому =)

windows10 ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Это универсальный повседневный пользовательский язык для любых прикладных задач

Ложь.

designed primarily for embedded use in applications

А Питон как раз для скриптухи создавался, без всяких там встроенных интенций.

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

Ложь.

Не. Ты просто не понимаешь что такое встраиваемость для lua.
Вернее ты неправильно интерпретируешь эту фундаментальную вещь для lua. Луа, неизбежно встраиваемая, она не существует в не встраиваемом виде. И прикладное применение никак не конфликтует со встраиванием, а лишь является одной из четырёх фундаментальных целей языка.

А Питон …

Lua > Python

LINUX-ORG-RU ★★★★★
() автор топика
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)

Нафиг этот ваш изврат на lua, когда есть borg на python, который умеет в инкрементальные бэкапы.

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

Ну не надо, значит не надо. А так borg на python разве не просто
дёргает rsync с нужными ключами для инкрементальных бэкапов?
И если нет разницы, зачем платить больше?

Моё дело, выложить. А что с этим потом делать или не делать, дело не моё :D

LINUX-ORG-RU ★★★★★
() автор топика
Последнее исправление: LINUX-ORG-RU (всего исправлений: 3)
Ответ на: комментарий от LINUX-ORG-RU

Я не уверен, что borg дергает rsync, прямой зависимости пакета от rsync не вижу, а в коде там очень много всего, для того чтобы с ходу разобраться, что происходит.
Возможно, что там свой велосипед изобретен, но главное что удобно, есть возможность сразу смонтировать любой бэкап в ro.

Khnazile ★★★★★
()
Ответ на: комментарий от sanyo1234

Чем оно лучше ZFS?

Нет смысла сравнивать, потому что предназначения у инструментов разные. ZFS — не бекапилка. В лучшем случае это один из кубиков, из которых в итоге можно собрать бекапилку.

i-rinat ★★★★★
()
Ответ на: комментарий от posixbit

Ничем не лучше, вопрос личных предпочтений. Оба лучше, чем просто создание zip-архивов.

i-rinat ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Мне просто нужно положить файлы из места А в место Б. Архивировать или нет, паролить или нет, обновлять только новое или всё принудительно, удалять из бекапа то что нет в источнике или сохранять, держать одну копию или версионировать по датам. Вот это ровно всё что есть и всё что мне надо.

У меня была своя портянка, правда на bash и использованием инкрементных архивов tar. Но потом надоело выбирать, какой архив должен быть полный, а какой инкрементный, и я попробовал Attic. И стало проще.

i-rinat ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

А EXT4 на внешнем носителе

А, т.е. ФС на внешнем носителе д.б. EXT4. Спасибо, хоть какая-то конкретика пошла.

tiinn ★★★★★
()
Ответ на: комментарий от amd_amd

нивкоем случае никогда не берите кредитов или ипотек

Допустим, я могу себе это позволить. Но, что делать молодой семье?

tiinn ★★★★★
()
Ответ на: комментарий от sanyo1234

Собрать второй ПК с Авито из комплектующих 10 летней давности стоит сущие копейки, 2-3 тыр

За 2-3 тыр. там будет винт HDD на 250Гб, полудохлый. Оно серьёзно годится для бакапов? Новый терабайтник выйдет вам ещё в 5 тыр.

tiinn ★★★★★
()
Ответ на: комментарий от Jurik_Phys

Никогда не производил сравнение. Не думаю, что дедуплицирующие бекапилки настолько сильно отличаются, чтобы прыгать с одной на другую. Переход от простых tar-файлов к системе бекапа со сжатием, шифрованием и дедупликацией — существенный апгрейд. Переход между подобными системами — уже не очень.

Предлагаю просто поискать сравнения в интернете. Судя по поверхностному поиску, их достаточно много.

i-rinat ★★★★★
()
Ответ на: комментарий от iron

Да не, дело не в библиотеках. Lua сама по себе такая же голая как и Си и из коробки там практически ничего нет (и это хорошо). Тут дело больше в самом процессе и ещё нескольких важных штуках. А так, по сути Lua это и есть библиотека, конфиг на стероидах. :)

Да и запросы у меня в этом вашем пограммировании оч скромные, я же только для себя пишу всякую мелочёвку.

LINUX-ORG-RU ★★★★★
() автор топика
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от tiinn

За 2-3 тыр. там будет винт HDD на 250Гб, полудохлый. Оно серьёзно годится для бакапов? Новый терабайтник выйдет вам ещё в 5 тыр.

Причём тут носитель? У ТС-а есть винт, речь о дополнительном хосте с персональным RAM и PSU.

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

А из смартфона как бэкапить?

Сначала на промежуточный хост любым обычным способом. А потом уже с него моим способом.

sanyo1234
()
Ответ на: комментарий от LINUX-ORG-RU

Lua сама по себе такая же голая как и Си

Та дело не в простоте. А в том, что если будет нужно на быструю руку сделать бекап на каком-то сервере, то ставить lua за ради этого скрипта неохота. Было бы на сях, можно было бы просто залить бинарник и забекапить то что нужно.

iron ★★★★★
()
Ответ на: комментарий от tiinn

что делать молодой семье

в россии сокращается численносить населения 30 лет подряд и квартиры от усопших переходят по наследству потомкам оставшихся в живых, мне уже 3 такие квартиры перешло - задолбался коммуналку оплачивать, пришлось даже одну квартиру сдавать, что б оплатить остальные.

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

в россии сокращается численносить населения 30 лет подряд и квартиры от усопших переходят по наследству потомкам оставшихся в живых,

Но и продолжительность жизни растёт. Так что, молодой семье до сего тягостного события порой 30 лет ждать приходится. Не вариант.

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

родившиеся до него будут жить долго

мой прадед умер в 96 лет, дед в 85, отец в 61 и все это произошло до ковида.

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

мой прадед умер в 96 лет, дед в 85, отец в 61 и все это произошло до ковида.

А вам 25 лет, я правильно понимаю?

tiinn ★★★★★
()
Ответ на: комментарий от amd_amd

Так, какая же вы молодёжь? Я ж о том и говорю,

молодой семье до сего тягостного события порой 30 лет ждать приходится.

вы только подтверждаете это правило.

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

30 лет ждать

мой отец умер когда моему старшему сыну было 5 лет… а что плохого жить с родителями? я родился и вырос в семье где 3 поколения вместе жили.

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

мой отец умер когда моему старшему сыну было 5 лет

Не у всех так получается. Я ж говорю, нередко хата освобождается, когда ваши дети уже своими семьями обзавелись.

а что плохого жить с родителями?

Целиком и полностью зависит от родителей, что они за люди. Вон, чувак живёт в пятикомнатной квартире, в отдельной комнате, бодрствует по ночам - он и родителей видит 2 раза в сутки. Можно сказать, и ничего плохого. А бывает, когда все друг у друга на головах сидят и активно срут - тогда ничего хорошего.

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

Не у всех так получается.

да ты чего это трагедия все моей жизни - я до сих пор оправиться не успел

активно срут

да уж - веселенькая у тебя семейка… у нас всё было не так - мы все помогали друг другу, старые малым, а малые старым.

amd_amd ★★★★★
()
Последнее исправление: amd_amd (всего исправлений: 1)
Ответ на: комментарий от amd_amd

Лично у меня - тоже, все всем помогали. Но, во-первых, втроём в двухкомнатной квартире - не сепарируешься, во-вторых, мать постоянно вмешивается в мою жизнь и настаивает, что я делать должен, а что нет. И да, первых двух моих жён она на дух не выносила, так что я даже не пытался их в дом привести.

Тут без вариантов надо жить одному, что я и делаю.

tiinn ★★★★★
()
Последнее исправление: tiinn (всего исправлений: 1)
Ответ на: комментарий от anc

Это хорошо, когда старшее поколение способно с барского плеча выделить молодой семье миллионы на квартиру, пусть в долг. А если не способно?

tiinn ★★★★★
()
Последнее исправление: tiinn (всего исправлений: 1)
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)