简体   繁体   English

Tar error:通过Cron / PHP运行时存档中的意外EOF

[英]Tar error: Unexpected EOF in archive when running via Cron/PHP

I have a PHP console script that is called via cron which itself among other things creates a tar file of a directory. 我有一个通过cron调用的PHP控制台脚本,它本身创建了一个目录的tar文件。

When calling the PHP script via cron the the tar file is not created correctly. 通过cron调用PHP脚本时,无法正确创建tar文件。 The following error is given when viewing the tar file: 查看tar文件时会出现以下错误:

gzip: stdin: unexpected end of file
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now

When calling the PHP script manually via console the tar file is created correctly. 通过控制台手动调用PHP脚本时,正确创建了tar文件。 The cron log output shows no errors. cron日志输出显示没有错误。

Here the tar call form the PHP script. 这里tar调用形成PHP脚本。

 exec("cd $this->backupTempFolderName/$id; tar -czf ../../$this->backupFolderName/$tarFileName $dbDumpFileName documents");

Dose anybody have an idea why the tar is created correctly when manually called and fails when called via cron? 任何人都知道为什么在手动调用时正确创建tar并在通过cron调用时失败?

Update : The error given while creating the tar file via cron is: 更新 :通过cron创建tar文件时给出的错误是:

tar: ../../backup/20150819-060003.tar.gz: Wrote only 4096 of 10240 bytes
tar: Error is not recoverable: exiting now

Sometimes the error is: 有时错误是:

tar: ../../backup/20150819-054002.tar.gz: Cannot write: Broken pipe
tar: Error is not recoverable: exiting now

As said before, the when executed via cron the tar file is created, but always 50% of the correct size (when manually executing the script): 如前所述,当通过cron执行时,tar文件被创建,但总是50%的正确大小(当手动执行脚本时):

-rw-r--r--  1 gtz gtz 1596099468 Aug 19 06:25 20150819-042330.tar.gz <- Manually called skript, working tar
-rw-r--r--  1 gtz gtz  858570752 Aug 19 07:21 20150819-052002.tar.gz <- Script called via cron, broken tar

Update 2 更新2

After doing some further research based on the input given here, might should add that the cron called script is running on a virtual private server - I suspect that some limitations may exist for cron jobs that are not documented by the hoster (only limit on minimum repetition time is given in the docs). 在根据此处给出的输入做了一些进一步的研究之后,可能应该补充一个名为script的cron正在虚拟专用服务器上运行 - 我怀疑对于没有托管者记录的cron作业可能存在一些限制(仅限于最低限度)重复时间在文档中给出。

That error comes usually from lack of disk space. 该错误通常来自磁盘空间不足。

I would do some more researching on this subject, by adding some logs before and after the tar execution. 我会在tar执行之前和之后添加一些日志,对这个主题做更多的研究。

Also check what user your configuration is using for the cron job you have running the backup. 还要检查您的配置用于运行备份的cron作业的用户。 It can be some quota limit on that user as well, that doesn't happen when you run on the console outside cron. 它也可能是该用户的一些配额限制,当您在cron外部的控制台上运行时不会发生这种限制。

Ask your provider for quota limits on the VPS for users and for processes... That is what rings the bell here. 向您的提供商询问VPS对用户和流程的配额限制......这就是响铃。

I guess that you have a resource limitation As M. Ivanov has said, add this command in your PHP script: 我猜你有资源限制正如M. Ivanov所说,在你的PHP脚本中添加这个命令:

shell_exec("php -info");

and check this parameter both when you execute your script from command line and from cron job 从命令行和cron作业执行脚本时检查此参数

memory_limit => ???

You can also try to run your cron by enhancing the memory limit to 1600M 您还可以通过将内存限制增加到1600M来尝试运行您的cron

php -d memory_limit=1600M scriptCompressor.php

Hope that helps :) 希望有帮助:)

cronjobs by themselves usually don't have limits. cronjobs本身通常没有限制。 If you are using shared hosting they may have installed some enforcing scripts but I suspect they would also break your console backups. 如果您使用共享主机,他们可能已安装了一些强制执行脚本,但我怀疑它们也会破坏您的控制台备份。

If you are running cronjobs from some container, eg Drupal, they have special limits. 如果你从某个容器运行cronjobs,例如Drupal,它们有特殊限制。

Also check bash limits with: ulimit -a 还要检查bash限制: ulimit -a

Report disk space before backup starts and afterwards just in case. 在备份开始之前和之后报告磁盘空间以防万一。 It's usually quite small on VPS. 它在VPS上通常很小。

You may want to try creating the tarball directly from PHP to avoid the exec call. 您可能想尝试直接从PHP创建tarball以避免exec调用。 See this answer: https://stackoverflow.com/a/20062628/5260945 . 请参阅此答案: https//stackoverflow.com/a/20062628/5260945

Also, looking at your cron entry, there is no leading slash on your example. 另外,查看您的cron条目,您的示例中没有前导斜杠。 I know this could just be a typo for the comment, but make sure you have an absolute path for the cd command. 我知道这可能只是评论的错字,但要确保你有一个cd命令的绝对路径。 The default environment for a cron job is not the same as for your login shell. cron作业的默认环境与登录shell的默认环境不同。

I am sure its memory or execution time problem. 我确定它的内存或执行时间问题。 Do one thing run the same script for directory which contains only single test file and check the output, if your script works in this scenario then 100% sure its memory problem. 对于仅包含单个测试文件的目录运行相同的脚本并检查输出,如果您的脚本在此方案中工作,则100%确定其内存问题。

try to tweak memory parameter and execute your script. 尝试调整内存参数并执行脚本。

I hope this help you. 我希望这对你有帮助。

Thanks 谢谢

Looking at the following error. 看下面的错误。

tar: ../../backup/20150819-054002.tar.gz: Cannot write: Broken pipe
tar: Error is not recoverable: exiting now

I see that as the exec function in the PHP script is not blocking or causing an error prematurely. 我看到,因为PHP脚本中的exec函数没有阻塞或过早地导致错误。 So the PHP session that get's called during the Cron job exits before the command finishes. 因此,在命令完成之前,在Cron作业期间调用的PHP会话将退出。 This is just a guess but you can try to send this to the background when you run it from Cron. 这只是猜测,但是当您从Cron运行它时,您可以尝试将其发送到后台。

exec("cd $this->backupTempFolderName/$id; tar -czf ../../$this->backupFolderName/$tarFileName $dbDumpFileName documents &");

This command should be blocking so this is just a shot in the dark. 这个命令应该是阻塞的,所以这只是在黑暗中拍摄。

http://php.net/manual/en/function.exec.php http://php.net/manual/en/function.exec.php

Error occurs when you trying to execute the php file and gives EOF error. 当您尝试执行php文件并出现EOF错误时发生错误。 It means somewhere in your php file you must check the code of your cron file it may happen that you forget to complete the brackets of the condition or class etc... 它意味着你的php文件中的某个地方你必须检查你的cron文件的代码,你可能会忘记完成条件或类等的括号...

Good luck ['} 祝好运 ['}

To write the errors to the log when executed via cron replace >/paht/to/application/app/logs/backup-output.log in the cron line by 2>&1 >/path/to/application/app/logs/backup-output.log Also check the path in the cron line .. maybe the change-dir is not working as you might think. 通过cron替换>/paht/to/application/app/logs/backup-output.log cron行中的>/paht/to/application/app/logs/backup-output.log并通过2>&1 >/path/to/application/app/logs/backup-output.log将错误写入2>&1 >/path/to/application/app/logs/backup-output.log还检查cron行中的路径..也许change-dir没有像你想象的那样工作。 Try printing getcwd() to a log or something, when running the php script from cron. 当从cron运行php脚本时,尝试将getcwd()打印到日志或其他东西。

Edit: I wonder why this was voted not useful . 编辑:我想知道为什么这被投票not useful The questioner mentioned that no errors are printed to the log when the cron executes the script. 提问者提到当cron执行脚本时,没有错误打印到日志中。 Thats not hard to imagine as > just redirects the STDOUT and not the STDERR (on which php errors would get printed) to the log. 这不难想象,因为>只是将STDOUT重定向到日志而不是STDERR(将错误打印出来的php)。 So adding 2>&1 might reveal some new informations. 因此,添加2>&1可能会显示一些新信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM