Backup

僅在連接電源且僅在時間視窗內備份

  • April 5, 2017

我在執行 Ubuntu 16.04 的筆記型電腦上使用 Deja Dup(Ubuntu 的標準備份應用程序)進行每日備份。創建備份需要大量電力,這就是為什麼我只希望在筆記型電腦連接到電源時自動啟動備份。

此外,我不希望從本地時間 8:00 到 9:45(24 小時制)(即 CET/CEST)自動啟動備份。

最後,我不希望每天自動創建多個備份,但希望盡可能自動創建備份。我不在乎是否考慮手動啟動的備份。

可以使用命令啟動備份

deja-dup --backup

,但是,我希望它以最低優先級完成,這樣其他應用程序就不會被它拖慢,所以它是:

nice -n 19 deja-dup --backup

當然,其他讓 Deja Dup 啟動備份的方法也是可以接受的。

當然,我可以通過編寫完全符合我要求的程序或腳本來強制解決問題。但是,它是 Linux,可能有一種更簡單、更優雅的方式。我想它可能仍然會產生一個腳本,但它可能比我在強迫我找到解決方案時想出的更短、更優雅。但請不要用這個打高爾夫球。:D

我現在基本上拿著一個巨大的大錘通過編寫腳本解決了這個問題。

首先,安裝 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

我能想到的最優雅的解決方案是設置一個 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

引用自:https://unix.stackexchange.com/questions/336124