Eu basicamente peguei uma marreta gigante e matei o problema escrevendo um script.
Primeiro, instale a interface de linha de comando do PHP, por exemplo via
sudo apt install php-cli
Estou supondo que o PHP 7 esteja instalado. Se você usa o PHP 5, remova : int
do cabeçalho do método determineTimeUntilBackup()
.
Em seguida, salve o script a seguir que eu escrevi (que não tem nenhuma garantia e não foi testado, mas tenho um bom pressentimento sobre isso e fiquei um pouco bêbado ao escrevê-lo (antes de postar essa resposta)) em um arquivo :
#!/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);
}
Tornar o arquivo executável, por exemplo, via:
chmod 755 backup.php
Em seguida, adicione o arquivo aos aplicativos de inicialização. Como isso é feito depende da sua distro. Para o Ubuntu, abra "Startup Applications" do painel e crie uma nova entrada. Como o comando, basta digitar o caminho do arquivo criado acima.
Eu não adicionei suporte para a restrição na hora do dia, já que minha circunstância pessoal exige que isso não exista mais, mas pode ser facilmente adicionado.
Editar: notei que os relatórios da bateria estão descarregando o tempo todo se meu laptop estiver conectado à energia elétrica por vários dias, fazendo com que o script não crie backups até que eu desconecte meu laptop por vários minutos e reconecte-o .
Para resolver esse problema, ele agora não lê se a bateria relata estar carregando ou descarregando, mas em vez disso lê o estado do adaptador de energia:
#!/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);
}
Você precisará, no entanto, de acpi
:
sudo apt install acpi