我有一个用于备份的 php 脚本。备份一直失败,因为第一个命令之一会引发错误并停止脚本。当我在终端中运行脚本时,它运行正常。我甚至设置了 cron 在下一分钟运行,所以我知道机器处于活动状态,外部硬盘已安装并可访问等,但它仍然失败。
这是我正在执行的命令:
/Users/kenny/google-cloud-sdk/bin/gsutil cp gs://backups.mydomain.com/sql/mydomain-db.2023-06-17-1687023004.sql.gz /Users/kenny/extdrive/backup.mydomain/backups/2023/sql/2023-06-17/mydomain-db.2023-06-17-1687023004.sql.gz 2>&1
我的日志显示:
复制 gs://backups.herdboss.com/sql/herdboss-db.2023-06-17-1687023004.sql.gz...
==> 注意:您正在下载一个或多个大文件,如果启用切片对象下载,下载速度会显著加快。此功能默认启用,但需要安装已编译的 crcmod(请参阅“gsutil help crcmod”)。
OSError:操作不允许。
错误:命令退出代码:1
一个可能的线索是,我查看了关于需要启用 crcmod 以提高下载速度的消息,但我已经安装了 crcmod。我按照说明操作gsutil help crcmod
,它说配置很好。
我不确定这是否有助于识别问题,但当我从 cron 运行与从命令行运行时似乎至少存在一些环境差异。
有任何想法吗?
如果重要的话,这里是我用来运行命令的 php:
$cmd = "$gsutil cp $gspath $backupdir/$filename";
execandlog($cmd);
function execandlog(string $command, string $inputtext = null, bool $shouldhorkonerrorexitcode = true, int &$exitcode = null): ?string {
$fullcommand = "$command 2>&1";
logmesg($fullcommand);
$descriptors = [
0 => ($inputtext === null) ? STDIN : ['pipe', 'r'],
1 => ['pipe', 'w'],
2 => STDERR,
];
$pipes = [];
$process = proc_open($fullcommand, $descriptors, $pipes);
$output = null;
if (is_resource($process)) {
if ($inputtext !== null) {
if (false === fwrite($pipes[0], $inputtext)) {
logmesg("ERROR: UNABLE TO WRITE TEXT TO INPUT PIPE");
exit(-1);
}
fclose($pipes[0]);
}
$output = '';
$commandoutputstream = $pipes[1];
while (false === feof($commandoutputstream)) {
$line = trim(fgets($commandoutputstream, 4096));
$output .= "$line\n";
logmesg($line);
}
fclose($commandoutputstream);
$status = proc_get_status($process);
$exitcode = $status['exitcode'];
proc_close($process);
if ($exitcode !== 0) {
// Something went wrong
logmesg("ERROR: COMMAND EXIT CODE: $exitcode");
if ($shouldhorkonerrorexitcode) {
exit(-1);
}
}
}
return $output;
}