我正在试图弄清楚为什么当从命令行执行时它可能无效。在完成渲染并使用ImageMagick将帧编译成GIF后,我正在向用户发送POV-Ray动画。我有通过mutt sleep发送一小时的电子邮件,以便有时间编译用户动画。 (我已将其更改为120秒,因此我无需等待一个小时进行故障排除。在这方面,我还让动画只有3帧,直到找出问题为止。)
每次用户点击我的网站上的动画时,都会创建一个新的bash文件animation_done_bash.sh,该文件会创建一个新文件夹,用于存储动画的帧并在其中包含animation_done_bash.sh。为了使PHP页面前进到下一页,bash文件在dev null中执行。我已经测试过,如果这是命令行上的问题,它在那里工作,所以我真的不知道是什么问题。
以下是使用shell_exec执行的代码和输出(我在我的php页面上回应,看看有什么问题):
$animation_done_email = "#!/usr/bin/bash \nsleep 120; mutt -s \"Animation Finished\" -a animation.gif -- ".$email." <email.txt;";
/*Creates new animation_done_bash each time user hits animate*/
$directory_bash = "./User_Files/Animation/".$location."/";
$filename_bash = 'animation_done_bash.sh';
$handler_bash = fopen($directory_bash.$filename_bash, "w");
fwrite($handler_bash, $animation_done_email);
fclose($handler_bash);
/*Need to change the permissions on bash file so it can execute*/
chmod($directory_bash."/animation_done_bash.sh", 0777);
$command_5 = 'cd /home/ouraccount/public_html/User_Files/Animation/'.$location.'/; bash animation_done_bash.sh > /dev/null 2>/dev/null &';
$shellOutput = shell_exec($command_5);
其中$ email是用户的电子邮件,$ location是存储帧的文件夹。 email.txt存储在同一文件夹中。
输出: cd / home / ouraccount / public_html / User_Files / Animation / ani_51 /; bash animation_done_bash.sh&gt; / dev / null 2&gt; / dev / null&amp;
非常感谢任何指导。谢谢!
答案 0 :(得分:1)
在这种情况下推送(在渲染操作完成时调用脚本)更适合轮询(定期检查渲染操作是否完成)。
如果你不能推,只用一种语言,不要创建bash和PHP的混合。 以下是您可以尝试的两个可能适合您情况的示例:
如果渲染命令在完成后返回的示例:
<?php
/** PHP wrapper around rendering command X that mails the output **/
// Don't write attachment code yourself, use a class like PHPMailer: https://github.com/Synchro/PHPMailer
require_once('class.phpmailer.php');
// Ignore user browser close, rendering takes a long time
ignore_user_abort(true);
// On windows you'll also need to set_time_limit to something large. On Unix PHP doesn't count things like database queries and shell commands, on Windows it does
// Execute render command, don't forget to escape if you use user input
// Script will only continue once renderer returns. If renderer return before rendering is finished you cannot use this
$render_output = shell_exec('renderer input.file output.file');
// Could also be done in PHP for finer control and error handling
$imagemagick_output = shell_exec("convert output.file animation.gif");
unlink("output.file");
$mail = new PHPMailer();
$mail->addAttachment('animation.gif');
// etc.
unlink("animation.gif");
?>
如果渲染命令在完成之前返回的示例:
<?php
/** PHP wrapper around rendering command X that mails the output **/
// Don't write attachment code yourself, use a class like PHPMailer: https://github.com/Synchro/PHPMailer
require_once('class.phpmailer.php');
// Ignore user browser close
ignore_user_abort(true);
// Execute render command, don't forget to escape if you use user input
// If renderer returns before file is finished use this
$render_output = shell_exec('renderer input.file output.file 2> error.file');
// Wait for rendering to finish
// Implement these function, e.g. file_exists for output.file or error.file
while(!rendering_has_failed() && !rendering_is_finished()) {
sleep(15*60); // Low-resource wait for 15 minutes
}
// Could also be done in PHP for finer control and error handling
$imagemagick_output = shell_exec("convert output.file animation.gif");
unlink("output.file");
$mail = new PHPMailer();
$mail->addAttachment('animation.gif');
// etc.
unlink("animation.gif");
?>