Запуск внешнего приложения в PHP (exec, system, popen, passthru, proc_open)

19.06.2007

Запустить внешнее (чаще всего консольное) приложение в том же Linux в php можно разными способами. Все зависит от настроек безопасности (вроде включенности safe mode) и вообще операционной системы. В качестве примера использования дан пример получения вывода работы программы (очень частая фукнция). Вывод собирается в переменную $output. Если он не нужен, то можете его просто не получать и вызывать функцию без лишних манипуляций с переменными.

Exec


Exec – старая и известная всем функция. Работает и под Windows и под Linux. В случае работы из safe_mode запускает приложения только из директории определенной в параметре safe_mode_exec_dir в php.ini. Использование:
	exec("команда",$output); 

Shell_Exec


Алиасом для shell_exec является использование обратных кавычек (найдите букву Ё на клавиатуре :)). Использование:
	$output = shell_exec("команда"); 

System


Си-подобная фукнция system, ничего интересного, кроме того, что свой вывод она сразу отправляет в браузер, что не всегда удобно, поэтому надо использовать функции буферизации для того, что бы поймать ее вывод:
	ob_start();
	system("команда");
	$output = ob_get_contents();
	ob_end_clean();

Passthru


Основное применение функция passthru находит тогда, когда вывод какой-либо запускаемой программы не текстовый и хотелось бы сразу отправить его в браузер (ну картинка, например, какая-нибудь). Ее особенностью является то, что при ее использовании желательно писать полный путь до приложения, прямо от корня файловой системы.
	ob_start();
	passthru("команда");
	$output = ob_get_contents();
	ob_end_clean();

Popen


Чисто юниксовая команда popen открывает процесс как файл который можно или читать или писать. Работать надо с ней аккуратно и все за собой закрывать, ибо это форки, а форки страшны зомбарями (хотя может я и перестраховываюсь).
if( is_resource($f = popen("команда","r")) ) {
	$output = "";
	while(!feof($f)) { 
		$output .= fread($f,1024);
	}
	pclose($f);
}

Proc_open


Фукнция proc_open тоже специфична только для юникс систем. В коде приведенном ниже вторым аргументом идет некий массив. Ничего сложного, это просто дескрипторы для стандартного ввода, вывода и вывода ошибок и то, в каком режиме (запись, чтение или добавление) мы их открываем.
if(is_resource($process=proc_open("команда",array( 0 => array('pipe','r'), 
1 => array('pipe','w'), 2 => array('pipe','w')),$pipes))) {
	$output = "";
	while(!feof($pipes [ 1 ])) $output .= fread($pipes[1],1024);
	fclose($pipes[0]);
	fclose($pipes[1]);
	fclose($pipes[2]);
	proc_close($process);
}

Вот собственно и вся методика запуска приложений из под PHP. Ничего сложного, все осуществимо. Не поленитесь сходить по ссылкам на php.net и почитать доки. Там куча интересных и очень полезных примеров. Время вы точно не потеряете.


Комментирование этой статьи закрыто

Комментарии [8]

  1. Сен 21, 04:36 , pro

    это хорошо, когда есть описание разных вариантов, в одной теме.. и главное понятно

    нет ничего сложного, если есть доки

    один мой знакомый говорит: я ничего не знаю, я просто знаю в каком месте найти ответ на заданный вопрос

  2. Окт 31, 18:09 , Я

    круто!

  3. Дек 9, 07:51 , rem_lex

    Это все конечно очень замечательно, но есть одна трабла, которую пока не асилил, может есть какие-то решения:
    Исходное:
    1) Linux Debain Etch 4.0
    2) Apache+php_mod и прочее
    3) есть php скрипт в котором пытается вызваться через функцию exec (так же пробовалось через все остальные) системная комманда sasldblistusers2 или некоторые другие
    Проблема:
    Некоторые команды можно запустить только от имени суперпользователя
    Такое достоверно, потому что команда типа ping или некоторые прочие “безвредные” команды выполняются без проблем. Для того что бы выполнить защищенные команды есть вариант apache запускать от root, т.к. от того же имени что и апач запускаются скрипты, но это крайне не секурно.
    Какие будут варианты?

  4. Дек 9, 12:44 , Dead Krolik

    Я конечно не линуксоид, но даже я слышал о sudo.

  5. Дек 11, 02:26 , rem_lex

    суда, таки помогло )
    тем кому интересно, про sudo – можно почитать здесь

    маленький hint: что бы не мучатся с афторизацией скриптов можно в файл /etc/sudoers вставить строчку:
    www-data ALL=(ALL) NOPASSWD:ALL
    тогда для скриптов запускаемых от апачи не будет требоваться авторизация паролем )

  6. Дек 25, 22:07 , PhoeniX

    Apache Module mod_suexec. Но при использовании его все скрипты будут работать от имени, что чревато.
    судо тоже вариант, после долгой и нудной настройки.

  7. Мар 13, 19:20 , Kolyan

    Это все хорошо, но есть ли возможность запустить прогу Imagick к примеру, и продолжить выполнение скрипта? Т.е. отложенный результат. Иначе нужно будет ждать очень долго пока она выполниться обрабатываю штук 10 комманд. Экзекьюшена не хватить может. Пока не нашел вариантов… Интересуют конечно все это дело под шаред хостингом (не сейф мод)

  8. Мар 14, 00:08 , Dead Krolik

    Есть такая крутая функция fork. Только аккуратно надо ей пользоваться.

Комментирование этой статьи закрыто

Кто я


Возраст: 23
Профессия: заяц


Категории


Полезные ссылки


Стишок

Зайчик-зайчик, скок-поскок!
Н-нна тебе дробину в бок!
Не с капустой же мы будем
Жрать на Новый год пирог...

eu-shestakov.livejournal.com