Работа с PHP не дает результата
Я боролся с exec()
, пытаясь захватить вывод из него, когда добавляю задачу с помощью системной команды at
Unix. Моя проблема заключается в том, что он не выводит вывод при запуске из моего script, однако его запуск с терминала и PHP в интерактивном режиме выводит несколько строк.
Команда, которую я хочу выполнить, следующая:
echo exec("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes", $result);
var_dump()
дает string(0) ""
, а print_r()
выплескивает Array ()
. Я попытался использовать shell_exec()
, который выводит NULL
, однако следующие выходы hi
при запуске в контексте веб-страницы:
echo exec("echo 'hi'");
Это также выводит материал:
echo exec("atq");
Однако, как только я использую at
, ничего не выводится. Как я могу получить вывод:
exec("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes", $result);
Потому что в настоящее время он ничего не выводит при запуске как "обычный" через PHP через Apache, однако запуск команды в терминале, а также в интерактивной консоли PHP дает мне ожидаемый результат чего-то вроде:
php > echo exec("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes", $result);
warning: commands will be executed using /bin/sh
job 1219 at Sun Jun 10 12:43:00 2012
safe_mode
выключен, и я не могу понять, почему я не получаю никакого вывода из at
с помощью входящего в echo оператора, при выполнении atq
или любой другой оценки с помощью exec()
дает мне вывод, Я искал и читал этот вопрос, все это безуспешно.
Как я могу получить exec()
для возврата вывода из at
в строку или массив, если использовать второй аргумент с exec()
?
Ответы
Ответ 1
Рабочее, однострочное решение
Я не понимал, что это может быть так просто. Все, что требуется, - это перенаправить stderr в stdout, поместив 2>&1
в конец выполняемой команды. Теперь любой вывод из at
печатается на stdout, поэтому фиксируется exec()
:
echo exec("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes 2>&1", $result);
Мое старое решение:
Я пытался сохранить одно/двухстрочное решение, однако единственное, что работало в конце, заключалось в использовании proc_open()
, потому что at
записывается в stderr, который exec()
не читает! Я хотел бы поблагодарить @Tourniquet за указание на это, однако он удалил свой ответ. Цитировать:
Насколько я могу видеть, на выходах на stderr, которые не фиксируются Отв. Я не уверен в этом, но http://php.net/manual/en/function.proc-open.php, что позволяет прямой stderr в свою собственную трубу.
На самом деле это правильный способ делать вещи. Мое решение (потому что я только хочу stderr) должно было сделать это:
// Open process to run `at` command
$process = proc_open("echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes", array(2 => array("pipe", "w")), $pipes);
// Get stuff from stderr, because `at` prints out there for some odd reason
if(is_resource($process)) {
$output = stream_get_contents($pipes[2], 100);
fclose($pipes[2]);
$return_value = proc_close($process);
}
$output
теперь содержит все at
, напечатанные в stderr (что должно действительно идти в stdout, потому что это не ошибка), а $return_value
содержит 0
при успешном завершении.
Ответ 2
Здесь более сложное решение с proc_open. Я пишу этот ответ, потому что в моем случае обходной путь "2 > и 1" не работает.
function runCommand($bin, $command = '', $force = true)
{
$stream = null;
$bin .= $force ? ' 2>&1' : '';
$descriptorSpec = array
(
0 => array('pipe', 'r'),
1 => array('pipe', 'w')
);
$process = proc_open($bin, $descriptorSpec, $pipes);
if (is_resource($process))
{
fwrite($pipes[0], $command);
fclose($pipes[0]);
$stream = stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($process);
}
return $stream;
}
Примеры использования:
// getting the mime type of a supplied file
echo runCommand('file -bi ' . escapeshellarg($file));
Другой пример, используя параметр команда:
// executing php code on the fly
echo runCommand('/usr/bin/php', '<?php echo "hello world!"; ?>');
Другой пример с использованием параметра force (это может быть полезно для команд, которые будут изменять вывод во время процесса выполнения):
// converting an mp3 to a wav file
echo runCommand('lame --decode ' . escapeshellarg($source) . ' ' . escapeshellarg($dest), '', true);
Я надеюсь, что это поможет : -)
Ответ 3
Попробуйте создать минимальный (не) рабочий пример. Разбейте все, и одновременно проверяйте только одно.
Вот ваша ошибка в bash:
[email protected]:~/temp$ echo 'php -f /path/to/file.php foo=1' | at now + 1 minutes
at: pluralization is wrong
job 22 at Sun Jun 10 14:48:00 2012
[email protected]:~/temp$
Напишите minute
вместо og minutes
.
Мой вывод из at
отправляется мне по почте!