首页 > 解决方案 > rsync 后用 PHP 提取 .tar.gz

问题描述

我正在尝试提取我在管道中使用 bash 压缩的 .tar.gz。管道选择应使用更新打包的文件,rsync然后使用以下命令压缩它们tar

rsync -azp --files-from=${RSYNC_UPDATE_FILE} --ignore-missing-args src update
tar czf ${UFILE} update

当我使用 WinRar 之类的程序打开 .tar.gz 时,这些文件看起来是正确的。然后我在应用程序中使用 PHP 提取更新。

# Get the full path where it should be extracted
$dirpath = $dirpath ?: File::dirname($zippath);

$phar = new \PharData($zippath);

# Check if it's compressed: e.g. tar.gz => tar
$zip = $phar->isCompressed() ? $phar->decompress() : $phar;

try {
    # Extract it to the new dir
    $extracted = $zip->extractTo($dirpath);
} catch (\Exception $e ) {
    throw new CorruptedZip("Unable to open the archive.",424,$e);
}  

提取的文件具有正确的权限、目录结构等,但我猜它们仍然是压缩的。这些文件都包含许多字符串组,而不是 PHP 代码。

02a0 048b 2235 bca8 ad5e 4f7e d9be ed1f
5b00 24d5 9248 8994 2c75 f778 e293 74db
6401 a802 0af5 55e1 52fc fb37 80ff f99f

任何人都可以看到我错过了一步吗?

标签: phpbashpipelinetar

解决方案


知道了。该错误是由于未提及的过程造成的。UploadedFileLaravel 中的类将文件的 mimetype 解释为application/x-gzip,扩展名为空,因此生成的文件保存为[hashed_file_name].而不是[hashed_file_name].tar.gz. 然后(在另一台服务器上)我GuzzleHttp用来获取文件并Symfony猜测扩展名。

$extension = ExtensionGuesser::getInstance()->guess($contentType);

由于 mimetype,使用Content-Typeheader 来获取扩展名的重建文件只是.gz代替.tar.gzor .tgz。对我的上传脚本的更改修复了它。

$alias = $file->getClientOriginalName();
$mimetype = $file->getMimeType();
$extension = $file->guessClientExtension() ?: pathinfo($alias, PATHINFO_EXTENSION);

if ( ends_with($mimetype, 'x-gzip') && ends_with($alias, ['tar.gz', 'tgz']) ) {
    $mimetype = 'application/tar+gzip';
    $extension = 'tar.gz';
}

$hash = $file->hashName();
if ( ends_with($hash, '.') ) {
    $hash .= $extension;
}

$path = $file->storeAs($storage, $hash);

推荐阅读