2009-10-07 3 views
1

Использование PHP в Linux, я хотел бы определить, была ли успешно выполнена команда оболочки, выполняемая с помощью exec(). Я использую параметр return_var, чтобы проверить успешное возвращаемое значение 0. Это работает отлично, пока мне не нужно делать то же самое для процесса, который должен выполняться в фоновом режиме. Например, в следующей команде $ результата возвращает 0:PHP exec() возвращаемое значение для фонового процесса (linux)

exec('badcommand > /dev/null 2>&1 &', $output, $result); 

Я поставил редирект там нарочно, я не хочу, чтобы захватить какой-либо вывод. Я просто хочу знать, что команда выполнена успешно. Можно ли это сделать?

Спасибо, Брайан

ответ

3

Я думаю, что то, что вы пытаетесь сделать, это напрямую не возможно. Опираясь на процесс, вы позволяете скрипту PHP продолжить (и, возможно, выйти) до того, как будет найден результат.

Работать вокруг, чтобы иметь второй скрипт PHP (или Bash/etc), который просто выполняет выполнение команды и записывает результат в временный файл.

Основной скрипт будет что-то вроде:

$resultFile = '/tmp/result001'; 
touch($resultFile); 
exec('php command_runner.php '.escapeshellarg($resultFile).' > /dev/null 2>&1 &'); 

// do other stuff...  

// Sometime later when you want to check the result... 
while (!strlen(file_get_contents($resultFile))) { 
    sleep(5); 
} 
$result = intval(file_get_contents($resultFile)); 
unlink($resultFile); 

И command_runner.php будет выглядеть так:

$outputFile = $argv[0]; 
exec('badcommand > /dev/null 2>&1', $output, $result); 
file_put_contents($outputFile, $result); 

Его не очень, и там, конечно, место для добавления надежности и обработки одновременных казней, но общая идея должна работать.

+0

Большое спасибо за ответы, очень полезно. – Brian

1

Не используется метод exec(). Когда вы отправляете процесс в фоновый режим, он возвращает 0 к вызову exec, а php продолжит выполнение, нет способа получить окончательный результат.

pcntl_fork() однако отклонит ваше приложение, поэтому вы можете запустить exec() в дочернем процессе и оставить его до тех пор, пока он не завершится. Затем exit() со статусом, вызванным вызовом exec. В родительском процессе вы можете получить доступ к этому обратному коду с pcntl_waitpid()

1

Просто мой 2 цента, как об использовании оператора || или && оргий?

exec('ls && touch /tmp/res_ok || touch /tmp/res_bad'); 

А затем проверьте наличие файла.