仅在连接电源时且仅在时间窗口内进行备份

仅在连接电源时且仅在时间窗口内进行备份

我在运行 Ubuntu 16.04 的笔记本电脑上使用 Deja Dup(Ubuntu 的标准备份应用程序)进行日常备份。创建备份需要大量电量,这就是为什么我只希望在我的笔记本电脑连接到电源时自动启动备份。

此外,我不希望在当地时间(CET/CEST)8:00 到 9:45(24 小时制)自动启动备份。

最后,我不希望每天自动创建多个备份,但希望在可能的情况下自动创建备份。我不关心是否考虑手动启动的备份。

可以使用以下命令启动备份

deja-dup --backup

但是,我希望它以最低优先级完成,这样其他应用程序就不会因此而减慢速度,因此:

nice -n 19 deja-dup --backup

当然,使Deja Dup启动备份的其他方式也是可以接受的。

可以当然,通过编写完全按照我想要的方式编写程序或脚本,强制我找到解决方案。然而,它是 Linux,并且可能有一种更简单、更优雅的方法。我想它可能仍然会产生一个脚本,但它可能比我在强制解决方案时想出的更短、更优雅。但请不要用这个打高尔夫球。 :D

答案1

我能想到的最优雅的解决方案是设置一个 crontab,可以调整它以在特定时间范围内每天运行一次备份脚本。

对于“连接到电源”检查,此命令适用于我的情况:

root@debian:/home/gv/Desktop/PythonTests# upower -i /org/freedesktop/UPower/devices/line_power_AC |grep online
    online:              yes

您可以将其包含在您的脚本中,如下所示:

onpower=$(upower -i /org/freedesktop/UPower/devices/line_power_AC |grep online |awk -F " " '{print $NF}')
if [[ "$onpower" == "yes" ]];then 
deja-dup --backup
fi

答案2

我现在基本上拿着一个巨大的大锤通过编写脚本来解决这个问题。

首先,安装 PHP 命令行界面,例如通过

sudo apt install php-cli

我假设 PHP 7 已安装。如果您使用 PHP 5,请: intdetermineTimeUntilBackup()的方法标头中删除。

然后,将我编写的以下脚本(绝对没有任何保证,也没有经过测试,但我对它有很好的感觉,并且在编写它时(就在发布此答案之前)只是有点醉)保存到文件中:

#!/usr/bin/php
<?php
// CONFIGURATION
/**
* The command to execute to create a backup.
*/
define('backupCommand', 'nice -n 19 deja-dup --backup');

/**
* The minumem period of time between 2 backups in seconds.
*/
define('minimumBackupSeparation', 20*3600);

/**
* The minimum time between 2 checks of whether a backup should be created in
* seconds. Only positive integers are permitted.
*/
define('minimumWaitingTime', 300);

/**
* The path of the file in which the time stamp of the lasted back is stored.
*/
define('latestBackupTimestampFile', 'latestBackupTimestamp');
// END OF CONFIGURATION


// Checking for root.
if(posix_getuid() == 0) {
    die('Backup script runs as root. This is probably a bad idea. Aborting.'."\n");
}

if(minimumWaitingTime !== (int) minimumWaitingTime) {
    die('Configuration error: Minumem waiting time must be an int!'."\n");
}

if(minimumWaitingTime < 1) {
    die('Configuration error: Minimum waiting time too small!'."\n");
}


while(true) {
    $timeUntilNextBackup = determineTimeUntilBackup();

    if($timeUntilNextBackup === 0) {
        createBackup();
        continue;
    }

    if($timeUntilNextBackup < 0) {
        $timeUntilNextBackup = minimumWaitingTime;
    }

    sleep($timeUntilNextBackup);
}


/**
* Returns a non-negative int when waiting for a point in time, a negative int
* otherwise. If a backups should have been created at a point in the past,
* `0` is returned.
*/
function determineTimeUntilBackup() : int {
    $latestBackup = 0;

    if(file_exists(latestBackupTimestampFile)) {
        $fileContents = file_get_contents(latestBackupTimestampFile);
        if($fileContents != (int) $fileContents) {
            die('Error: The latest backup timestamp file unexpectedly doesn\'t '
                    .'contain a timestamp.'."\n");
        }

        $latestBackup = (int) $fileContents;
    }

    $idealTimeUntilNextBackup = $latestBackup + minimumBackupSeparation - time();
    if($idealTimeUntilNextBackup < 0) {
        $idealTimeUntilNextBackup = 0;
    }

    $batteryStateReading = exec("upower -i `upower -e | grep 'BAT'` | grep 'state'");
    if(empty($batteryStateReading)) {
        echo 'Unable to read battery state!'."\n";
    } else {        
        if(strpos($batteryStateReading, 'discharging') !== false) {
            // Not connected to power.
            return -1;
        }
    }

    return $idealTimeUntilNextBackup;
}


/**
* Creates a backup and notes it in the latest backup timestamp file.
*/
function createBackup() {
    file_put_contents(latestBackupTimestampFile, time());
    exec(backupCommand);
}

使文件可执行,例如通过:

chmod 755 backup.php

然后,将该文件添加到启动应用程序中。如何完成此操作取决于您的发行版。对于 Ubuntu,从仪表板打开“启动应用程序”并创建一个新条目。作为命令,只需输入您上面创建的文件的路径即可。

我没有添加对一天中时间限制的支持,因为我的个人情况不再需要此限制,但可以轻松添加。


编辑:我注意到,如果我的笔记本电脑已连接电源几天,电池报告会一直在放电,导致脚本无法创建备份,直到我将笔记本电脑与电源断开几分钟并重新连接。

为了解决这个问题,它现在不读取电池是否报告正在充电或放电,而是读取电源适配器的状态:

#!/usr/bin/php
<?php
// CONFIGURATION
/**
* The command to execute to create a backup.
*/
define('backupCommand', 'nice -n 19 deja-dup --backup');

/**
* The minumem period of time between 2 backups in seconds.
*/
define('minimumBackupSeparation', 20*3600);

/**
* The minimum time between 2 checks of whether a backup should be created in
* seconds. Only positive integers are permitted.
*/
define('minimumWaitingTime', 300);

/**
* The path of the file in which the time stamp of the lasted back is stored.
*/
define('latestBackupTimestampFile', 'latestBackupTimestamp');
// END OF CONFIGURATION


// Checking for root.
if(posix_getuid() == 0) {
    die('Backup script runs as root. This is probably a bad idea. Aborting.'."\n");
}

if(minimumWaitingTime !== (int) minimumWaitingTime) {
    die('Configuration error: Minumem waiting time must be an int!'."\n");
}

if(minimumWaitingTime < 1) {
    die('Configuration error: Minimum waiting time too small!'."\n");
}

// Don't back up within 5 minutes after bootup.
sleep(5*60);

while(true) {
    $timeUntilNextBackup = determineTimeUntilBackup();
    echo $timeUntilNextBackup."\n";

    if($timeUntilNextBackup === 0) {
        createBackup();
        continue;
    }

    if($timeUntilNextBackup < 0) {
        $timeUntilNextBackup = minimumWaitingTime;
    }

    sleep($timeUntilNextBackup);
}


/**
* Returns a non-negative int when waiting for a point in time, a negative int
* otherwise. If a backups should have been created at a point in the past,
* `0` is returned.
*/
function determineTimeUntilBackup() : int {
    $latestBackup = 0;

    if(file_exists(latestBackupTimestampFile)) {
        $fileContents = file_get_contents(latestBackupTimestampFile);
        if($fileContents != (int) $fileContents) {
            die('Error: The latest backup timestamp file unexpectedly doesn\'t '
                    .'contain a timestamp.'."\n");
        }

        $latestBackup = (int) $fileContents;
    }

    $idealTimeUntilNextBackup = $latestBackup + minimumBackupSeparation - time();
    if($idealTimeUntilNextBackup < 0) {
        $idealTimeUntilNextBackup = 0;
    }

    $batteryStateReading = exec("acpi -a");
        if(strpos($batteryStateReading, 'on-line') === false) {
            // Not connected to power.
            return -1;
        }


    return $idealTimeUntilNextBackup;
}


/**
* Creates a backup and notes it in the latest backup timestamp file.
*/
function createBackup() {
    file_put_contents(latestBackupTimestampFile, time());
    exec(backupCommand);
}

但是,您将需要acpi

sudo apt install acpi

相关内容