Я пытаюсь бежать curl
Команда в файле php и пытается вывести ее вывод в файл журнала ошибок. Все ошибки php перечислены в файле кроме ошибок, которые я получаю от exec()
функция. 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
Команда должна запустить процесс, если вы вышли из оболочки из-за зависания линии терминала. (Когда оболочка завершается, она отправляет SIGHUP своим дочерним процессам.) nohup
Вы можете запустить команду, а затем выйти из оболочки.
curl
команда действительно прекращена на SIGHUP. Вы можете использовать nohup
поставить процесс загрузки в фоновом режиме. Но ваша цель — захватить вывод команды, будь то 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
функция. Вы должны экранировать все аргументы оболочки, иначе оболочка будет интерпретировать свои специальные символы.
Точка с запятой
Строки разделяются точкой с запятой (;
) интерпретируются как разные команды. Так что ваши --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));
Других решений пока нет …