如何在 PHP 错误日志文件中获取命令行错误
How to get command line errors in the PHP error log file
我正在尝试 运行 PHP 文件中的 curl
命令,并试图在错误日志文件中列出其输出。除了我从 exec()
函数得到的错误外,所有 PHP 错误都列在文件中。我正在尝试的 PHP 代码是:
exec("nohup curl --output " . $_SERVER['DOCUMENT_ROOT'] . "/abc.mp3 http://192.99.8.170:8098/stream/1; --max-time $time_in_seconds > /devnull&");
如何在错误日志文件中获取此命令生成的错误?我用谷歌搜索了这个,但找不到足够的结果。
命令
命令本身存在几个问题。
exec("nohup curl --output ".$_SERVER['DOCUMENT_ROOT'] .
"/abc.mp3 http://192.99.8.170:8098/stream/1; --max-time $time_in_seconds > /devnull&");
(为清楚起见,我将原始行换行。)
nohup
不需要
nohup
命令的主要目的是在您因终端线路挂断而从 shell 注销时有一个进程 运行。 (当 shell 退出时,它会向其子进程发送 SIGHUP。)使用 nohup
可以启动命令,然后注销 shell.
curl
命令确实在 SIGHUP 上终止。您可以使用 nohup
将下载过程 运行 置于后台。但是你的 objective 是捕获命令的输出,无论是 STDIN 还是 STDOUT。了解命令何时完成工作以及如何完成工作也很重要。例如,在执行命令 同步 后,可以检查退出代码(零表示成功)并检查文件是否实际下载到文件系统:
$output_dir = empty($_SERVER['DOCUMENT_ROOT']) ?
'/tmp/default-download-dir' : $_SERVER['DOCUMENT_ROOT'];
if (!is_dir($output_dir)) {
if (!mkdir($output_dir, 0755, true))
die("Failed to create directory $output_dir");
}
$url = 'http://php.net/images/logo.php';
$output_file = "{$output_dir}/logo.svg"; ;
// 2>&1 redirects standard error descriptor (2)
// to the standard output descriptor (1)
$command = sprintf("curl -o %s %s 2>&1",
escapeshellarg($output_file),
escapeshellarg($url));
$output = [];
exec($command, $output, $exit_code);
if ($exit_code != 0) {
die("Failed to download $url to $output_file");
}
clearstatcache(true, $output_file);
if (!file_exists($output_file)) {
die("File $output_file not found on file system, command: $command");
}
echo "$url has been saved to $output_file:\n",
implode(PHP_EOL, $output), PHP_EOL;
输出
http://php.net/images/logo.php has been saved to /tmp/default-download-dir/logo.svg:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 2202 100 2202 0 0 4171 0 --:--:-- --:--:-- --:--:-- 4665
注意escapeshellarg
函数的使用。您应该转义所有 shell 参数,否则 shell 将解释其特殊字符。
分号
用分号分隔的字符串 (;
) 被解释为不同的命令。所以你的 --max-time $time_in_seconds > /devnull&
被解释为第二个命令。我不知道你试图实现什么,但你很可能不需要它。
重定向到 /dev/null
您的 > /devnull&
表达有误。您可能意味着重定向到 /dev/null
伪设备:> /dev/null
.
将输出捕获到不同的文件描述符
在上面的代码中,我们捕获了标准输出。如果您还想将输出捕获到其他文件描述符,则应该使用 proc_open()
函数:
$output_dir = empty($_SERVER['DOCUMENT_ROOT']) ?
'/tmp/default-download-dir' : $_SERVER['DOCUMENT_ROOT'];
if (!is_dir($output_dir)) {
if (!mkdir($output_dir, 0755, true))
die("Failed to create directory $output_dir");
}
$url = 'http://php.net/images/logo.php';
$output_file = "{$output_dir}/logo.svg"; ;
$command = sprintf("curl -o %s %s",
escapeshellarg($output_file),
escapeshellarg($url));
$descriptors = [
1 => ['pipe', 'w'], // stdout
2 => ['pipe', 'w'], // stderr
];
$proc = proc_open($command, $descriptors, $pipes);
if (!is_resource($proc))
die("Failed to open process for command $command");
if ($output = stream_get_contents($pipes[1]))
echo "Output: $output\n\n";
fclose($pipes[1]);
if ($errors = stream_get_contents($pipes[2]))
echo "Errors: >>>>>>>>\n$errors\n<<<<<<<\n\n";
fclose($pipes[2]);
$exit_code = proc_close($proc);
if ($exit_code != 0) {
die("Failed to download $url to $output_file");
}
clearstatcache(true, $output_file);
if (!file_exists($output_file)) {
die("File $output_file not found on file system, command: $command");
}
echo "$url\nhas been saved to $output_file\n";
输出
Errors: >>>>>>>>
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2202 100 2202 0 0 4231 0 --:--:-- --:--:-- --:--:-- 4735
<<<<<<<
http://php.net/images/logo.php
has been saved to /tmp/default-download-dir/logo.svg
(curl
将“详细”输出输出到标准错误描述符)
固定命令
鉴于上述情况,您的命令应按如下方式构建:
$url = 'http://192.99.8.170:8098/stream/1';
$command = sprintf("curl -o %s %s --max-time $time_in_seconds",
escapeshellarg($output_file),
escapeshellarg($url));
我正在尝试 运行 PHP 文件中的 curl
命令,并试图在错误日志文件中列出其输出。除了我从 exec()
函数得到的错误外,所有 PHP 错误都列在文件中。我正在尝试的 PHP 代码是:
exec("nohup curl --output " . $_SERVER['DOCUMENT_ROOT'] . "/abc.mp3 http://192.99.8.170:8098/stream/1; --max-time $time_in_seconds > /devnull&");
如何在错误日志文件中获取此命令生成的错误?我用谷歌搜索了这个,但找不到足够的结果。
命令
命令本身存在几个问题。
exec("nohup curl --output ".$_SERVER['DOCUMENT_ROOT'] . "/abc.mp3 http://192.99.8.170:8098/stream/1; --max-time $time_in_seconds > /devnull&");
(为清楚起见,我将原始行换行。)
nohup
nohup
命令的主要目的是在您因终端线路挂断而从 shell 注销时有一个进程 运行。 (当 shell 退出时,它会向其子进程发送 SIGHUP。)使用 nohup
可以启动命令,然后注销 shell.
curl
命令确实在 SIGHUP 上终止。您可以使用 nohup
将下载过程 运行 置于后台。但是你的 objective 是捕获命令的输出,无论是 STDIN 还是 STDOUT。了解命令何时完成工作以及如何完成工作也很重要。例如,在执行命令 同步 后,可以检查退出代码(零表示成功)并检查文件是否实际下载到文件系统:
$output_dir = empty($_SERVER['DOCUMENT_ROOT']) ?
'/tmp/default-download-dir' : $_SERVER['DOCUMENT_ROOT'];
if (!is_dir($output_dir)) {
if (!mkdir($output_dir, 0755, true))
die("Failed to create directory $output_dir");
}
$url = 'http://php.net/images/logo.php';
$output_file = "{$output_dir}/logo.svg"; ;
// 2>&1 redirects standard error descriptor (2)
// to the standard output descriptor (1)
$command = sprintf("curl -o %s %s 2>&1",
escapeshellarg($output_file),
escapeshellarg($url));
$output = [];
exec($command, $output, $exit_code);
if ($exit_code != 0) {
die("Failed to download $url to $output_file");
}
clearstatcache(true, $output_file);
if (!file_exists($output_file)) {
die("File $output_file not found on file system, command: $command");
}
echo "$url has been saved to $output_file:\n",
implode(PHP_EOL, $output), PHP_EOL;
输出
http://php.net/images/logo.php has been saved to /tmp/default-download-dir/logo.svg:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 2202 100 2202 0 0 4171 0 --:--:-- --:--:-- --:--:-- 4665
注意escapeshellarg
函数的使用。您应该转义所有 shell 参数,否则 shell 将解释其特殊字符。
分号
用分号分隔的字符串 (;
) 被解释为不同的命令。所以你的 --max-time $time_in_seconds > /devnull&
被解释为第二个命令。我不知道你试图实现什么,但你很可能不需要它。
重定向到 /dev/null
您的 > /devnull&
表达有误。您可能意味着重定向到 /dev/null
伪设备:> /dev/null
.
将输出捕获到不同的文件描述符
在上面的代码中,我们捕获了标准输出。如果您还想将输出捕获到其他文件描述符,则应该使用 proc_open()
函数:
$output_dir = empty($_SERVER['DOCUMENT_ROOT']) ?
'/tmp/default-download-dir' : $_SERVER['DOCUMENT_ROOT'];
if (!is_dir($output_dir)) {
if (!mkdir($output_dir, 0755, true))
die("Failed to create directory $output_dir");
}
$url = 'http://php.net/images/logo.php';
$output_file = "{$output_dir}/logo.svg"; ;
$command = sprintf("curl -o %s %s",
escapeshellarg($output_file),
escapeshellarg($url));
$descriptors = [
1 => ['pipe', 'w'], // stdout
2 => ['pipe', 'w'], // stderr
];
$proc = proc_open($command, $descriptors, $pipes);
if (!is_resource($proc))
die("Failed to open process for command $command");
if ($output = stream_get_contents($pipes[1]))
echo "Output: $output\n\n";
fclose($pipes[1]);
if ($errors = stream_get_contents($pipes[2]))
echo "Errors: >>>>>>>>\n$errors\n<<<<<<<\n\n";
fclose($pipes[2]);
$exit_code = proc_close($proc);
if ($exit_code != 0) {
die("Failed to download $url to $output_file");
}
clearstatcache(true, $output_file);
if (!file_exists($output_file)) {
die("File $output_file not found on file system, command: $command");
}
echo "$url\nhas been saved to $output_file\n";
输出
Errors: >>>>>>>>
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2202 100 2202 0 0 4231 0 --:--:-- --:--:-- --:--:-- 4735
<<<<<<<
http://php.net/images/logo.php
has been saved to /tmp/default-download-dir/logo.svg
(curl
将“详细”输出输出到标准错误描述符)
固定命令
鉴于上述情况,您的命令应按如下方式构建:
$url = 'http://192.99.8.170:8098/stream/1';
$command = sprintf("curl -o %s %s --max-time $time_in_seconds",
escapeshellarg($output_file),
escapeshellarg($url));