cPanel 的 cron 作业出于未知原因创建 PHP 文件的别名...?

发布于 2024-12-02 21:34:06 字数 1164 浏览 0 评论 0原文

我有一个 cron 作业设置,经常运行一些 PHP 脚本。问题是,每次运行脚本时,它都会创建一个别名,或者一个具有相同文件名并在末尾添加数字的空文件。

例如,其中一个文件是 activesessions_update.cron.php,这是其中的脚本:

<?php
  $memcache = new Memcache; 
  $memcache->connect('127.0.0.1', 11211);
  $activeSessions = $memcache->getStats(); 

  // using heredoc
$file_content = <<<TEXT
<?php

\$activeSessions = {$activeSessions['curr_items']};

?>
TEXT;

// this would be a user-defined function
file_put_contents("activesessions.php", $file_content);
?>

在我的路由文件夹中,它是这样的: https://i.sstatic.net/j3kp8.png

在 cPanel 中,cron 作业运行命令:

/usr/bin/wget http://domain.com/x/activesessions_update.cron.php

我不知道问题是什么。我被迫每周删除数以万计的空文件。请注意,我没有 PHP 编程经验,因为我自己没有编写代码,所以任何包含详细信息的回复将不胜感激。谁能指导我解决这个难题?

编辑:从我的主机的技术支持中得到了解决方案:

它没有准确记录,默认情况下使用 wget 下载文件。 因此,当您针对该 url 运行 wget 时,它会发出请求该文件, 并下载请求的输出,实质上保存了一份副本 如果您将其拉出,您会在浏览器中看到什么。通过添加 -O /dev/null 到你告诉它的命令而不是保存 输出到默认位置(通常是在任何地方) 调用 from) 将其保存到 /dev/null ,这实际上无处可去 (基本上只是把它扔掉)

I have cron jobs setup that runs a few PHP scripts often. The issue is that each time it runs a script, it create an alias of it, or an empty file with the same filename and a number added at the end.

For instance, one of the files are activesessions_update.cron.php, here is the script inside it:

<?php
  $memcache = new Memcache; 
  $memcache->connect('127.0.0.1', 11211);
  $activeSessions = $memcache->getStats(); 

  // using heredoc
$file_content = <<<TEXT
<?php

\$activeSessions = {$activeSessions['curr_items']};

?>
TEXT;

// this would be a user-defined function
file_put_contents("activesessions.php", $file_content);
?>

In my route folder, this is how it looks like: https://i.sstatic.net/j3kp8.png

In cPanel, the cron job runs the command:

/usr/bin/wget http://domain.com/x/activesessions_update.cron.php

I have no idea what the problem is. I am forced to delete 10,000s of these empty files every week. Please note that I have no experience in PHP programming as I did not code it myself so any replies would be appreciated with utter detail. Who can guide me to solve this puzzle?

EDIT: Got the solution from techincal support of my host:

It wasn't logging exactly, by default wget is used to download files.
So when you run wget against that url it goes out, requests the file,
and downloads the output of the request, essentially saving a copy of
what you would get in your browser if you pulled it up. By adding the
-O /dev/null to the command you are telling it that instead of saving
that output to the default location (generally wherever it was being
called from) to save it to /dev/null which is really just nowhere
(basically just throws it away)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

网白 2024-12-09 21:34:06

由于我们已经确定这些是由 cron 创建的日志文件,因此解决方法是让 PHP 脚本在运行时删除日志文件。将 activesessions_update.cron.php 更改为此 - 首先在不同的目录中备份原始版本!

我假设这些文件的创建方式是用户脚本以具有删除文件的权限运行。如果不是,这将不起作用。

<?php

  $memcache = new Memcache; 
  $memcache->connect('127.0.0.1', 11211);
  $activeSessions = $memcache->getStats(); 

  // Removed slightly pointless heredoc
  $file_content = "<?php\n\n\  $activeSessions = {$activeSessions['curr_items']};\n\n?>";

  // this would be a user-defined function
  // What does the above comment mean? Are you supposed
  // to replace this with some of your own code?
  file_put_contents("activesessions.php", $file_content);


  // ========================================================
  //     Everything below here is to delete old log files


  // Change this to the directory where the log files end up
  $logsdir = "/home/USER/";

  // Get the name of this file and length of the name
  $filename = basename($_SERVER['PHP_SELF']);
  $namelength = strlen($filename);

  // Strip any trailing slashes from $logsdir
  $logsdir = rtrim($logsdir,'/\\');

  // Open the logs directory
  if (!$dp = opendir($logsdir)) {
    trigger_error("Could not open logs directory '$logsdir' for reading, exiting...");
    exit;
  }

  // Loop through the files in the directory
  while ($file = readdir($dp)) {
    if (!in_array($file,array('.','..',$filename)) && strlen($file) > $namelength && substr($file,0,$namelength) == $filename) {
      // If the start of the file name is the same as this file,
      // and the file name length is longer than the length of the
      // name of this file, delete it.
      @unlink("$logsdir/$file");
    }
  }

  // Close the directory pointer
  @closedir($dp);

?>

我猜想您服务器上的 cron 守护进程配置为将其运行的所有 cron 作业的 STDOUT 和 STDERR 重定向到一个文件。这样的配置似乎很奇怪,因为它会导致像您遇到的问题。另外,它应该将它们重定向到基本上与脚本同名且末尾带有数字的文件,这似乎很奇怪。你可能会认为它们是 *.log 之类的。

此解决方案在任何时候仍会保留至少一个日志文件,因为您肯定无法删除当前正在写入的文件。

如果这确实有效,您可以安全地将相同的代码(从 ===== 注释行下方)复制/粘贴到 cron 作业调用并导致相同问题的任何其他文件中,只要它们是:

  • 在脚本所在的同一目录中创建日志文件
  • (您实际想要的)目录中的唯一文件,其中文件名以脚本文件的全名开头

Since we have established that these are log files created by cron, a work-around is to have the PHP script delete the log files as it is run. Change activesessions_update.cron.php to this - back up the original version in a different directory first!

I am assuming that the files are created in such a way that the user you script is run as has permissions to delete the files. If it is not, this wont work.

<?php

  $memcache = new Memcache; 
  $memcache->connect('127.0.0.1', 11211);
  $activeSessions = $memcache->getStats(); 

  // Removed slightly pointless heredoc
  $file_content = "<?php\n\n\  $activeSessions = {$activeSessions['curr_items']};\n\n?>";

  // this would be a user-defined function
  // What does the above comment mean? Are you supposed
  // to replace this with some of your own code?
  file_put_contents("activesessions.php", $file_content);


  // ========================================================
  //     Everything below here is to delete old log files


  // Change this to the directory where the log files end up
  $logsdir = "/home/USER/";

  // Get the name of this file and length of the name
  $filename = basename($_SERVER['PHP_SELF']);
  $namelength = strlen($filename);

  // Strip any trailing slashes from $logsdir
  $logsdir = rtrim($logsdir,'/\\');

  // Open the logs directory
  if (!$dp = opendir($logsdir)) {
    trigger_error("Could not open logs directory '$logsdir' for reading, exiting...");
    exit;
  }

  // Loop through the files in the directory
  while ($file = readdir($dp)) {
    if (!in_array($file,array('.','..',$filename)) && strlen($file) > $namelength && substr($file,0,$namelength) == $filename) {
      // If the start of the file name is the same as this file,
      // and the file name length is longer than the length of the
      // name of this file, delete it.
      @unlink("$logsdir/$file");
    }
  }

  // Close the directory pointer
  @closedir($dp);

?>

I guess the cron daemon on your server is configured to redirect STDOUT and STDERR of all the cron jobs it runs to a file. It seems odd that it is configured like this, as it will cause problems like you are having. Also, it seems very odd that it should redirect them to files that have, essentially, the same name of your script with a number on the end. You would have though they would be *.log or something.

This solution will still leave at least one log file in existence at any one time, because you definitely wont be able to delete the file that is currently being written to.

If this does work, you can safely copy/paste the same code (from below the ===== comment line) into any other files that are called by cron jobs and are causing the same problem, as long as they are:

  • creating the log files in the same directory that the script resides
  • the only file in the directory (that you actually want) where the file name starts with the full name of the script file
不气馁 2024-12-09 21:34:06

我敢打赌,这些是包含脚本输出的日志文件,由 cPanel 的 cron 创建。检查 cPanel 的配置并禁用日志记录(如果不需要)。

I would bet that these are log files containing the output of the script, created by cPanel's cron. Check you cPanel's configuration and disable logging if you don't need it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文