На моем компьютере разработчика и на моем сервере разные пути для разных версий Python.
Чтобы получить правильный путь к определенному исполняемому файлу Python, я сделал этот метод
static function pythonPath ($version='') {
$python = $version === '' ? 'python': '';
if (preg_match('/^\d(\.?\d)?$/', $version)) {
$python = 'python'.$version;
}
return trim(shell_exec("/usr/bin/which $python 2>/dev/null"));
}
На моей машине разработчика я могу сделать это
$> php -r 'require("./class.my.php"); $path=MyClass::pythonPath("2.7"); var_dump($path); var_dump(file_exists($path));'
string(18) "/usr/bin/python2.7"bool(true)
И на сервере я получаю это
$> php -r 'require("./class.my.php"); $path=MyClass::pythonPath("2.7"); var_dump($path); var_dump(file_exists($path));'
string(27) "/opt/python27/bin/python2.7"bool(true)
Но если я использую этот метод на fastCGI, результат which
пуст (CentOS 6).
Насколько я прочитал, which
поиск по пользователю $PATH
, И это может быть причиной того, что я не получил никакого результата для which python2.7
так как пользователь, который выполняет сценарий (мое предположение httpd
) имеет не тот же путь, что и пользователь учетной записи.
Итак, как я могу найти исполняемый путь в сценарии fastCGI?
Имея пользовательские пути разные. (Непроверенное предположение: продолжал использовать which
и получить сначала переменную полного пути моей учетной записи сервера и загрузить его до which
)
На моем сервере скрипты запускаются пользователем «nobody».
печать $PATH
изнутри скрипта покажет что /usr/bin
это единственный путь к исполняемым двоичным файлам, заданный для этого пользователя и использующий сценарии fastCGI.
Хитрость заключалась в поиске переменных среды моего пользователя перед выполнением which
,
Так как файлы профиля bash могут различаться по имени и, следовательно, по моему каталогу скриптов, я сделал эту функцию, чтобы получить правильный путь.
static function getBashProfilePath () {
$bashProfilePath = '';
$userPathData = explode('/', __DIR__);
if (!isset($userPathData[1]) || !isset($userPathData[2]) || $userPathData[1] != 'home') {
return $bashProfilePath;
}
$homePath = '/'.$userPathData[1].'/'.$userPathData[2].'/';
$bashProfileFiles = array('.bash_profile', '.bashrc');
foreach ($bashProfileFiles as $file) {
if (file_exists($homePath.$file)) {
$bashProfilePath = $homePath.$file;
break;
}
}
return $bashProfilePath;
}
Окончательная реализация для получения двоичного пути Python была
static function pythonPath ($version='') {
$python = $version === '' ? 'python': '';
if (preg_match('/^\d(\.?\d)?$/', $version)) {
$python = 'python'.$version;
}
$profileFilePath = self::getBashProfilePath();
return trim(shell_exec(". $profileFilePath; /usr/bin/which $python 2>/dev/null"));
}
Других решений пока нет …