在PHP中获取Linux发行版名称

5

有没有一种方法可以在PHP中找出远程服务器的Linux发行版名称?

$_SERVER['HTTP_USER_AGENT']中提取只是客户端机器的操作系统名称,而不是我想要的。 我尝试过 php_uname()

echo 'Operating System: '.php_uname('s').'<br>'; // echo PHP_OS;
echo 'Release Name: '.php_uname('r').'<br>';
echo 'Version: '.php_uname('v').'<br>';
echo 'Machine Type: '.php_uname('m').'<br>';

但是模式 s 仅返回内核类型 - Linux。

Operating System: Linux
Release Name: 2.6.32-431.29.2.el6.x86_64
Version: #1 SMP Tue Sep 9 21:36:05 UTC 2014
Machine Type: x86_64

我想知道它是Fedora、CentOS还是Ubuntu等操作系统。这可行吗?我也尝试过posix_uname(),但出现了错误。
致命错误:调用未定义的函数posix_uname()。

可能是如何解释php_uname的输出的重复问题。 - kero
1
不是重复的问题,因为它询问的是分发方式,而不是平台。 - lxg
3个回答

3
在Linux系统上,通常会有像/etc/lsb-release/etc/os-release这样的文件,其中包含有关发行版的信息。
您可以在PHP中读取它们并提取它们的值。
if (strtolower(substr(PHP_OS, 0, 5)) === 'linux')
{
    $vars = array();
    $files = glob('/etc/*-release');

    foreach ($files as $file)
    {
        $lines = array_filter(array_map(function($line) {

            // split value from key
            $parts = explode('=', $line);

            // makes sure that "useless" lines are ignored (together with array_filter)
            if (count($parts) !== 2) return false;

            // remove quotes, if the value is quoted
            $parts[1] = str_replace(array('"', "'"), '', $parts[1]);
            return $parts;

        }, file($file)));

        foreach ($lines as $line)
            $vars[$line[0]] = $line[1];
    }

    print_r($vars);
}

虽然不是最优雅的PHP代码,但它可以完成任务。

这将给你一个类似于数组的结果:

Array
(
    [DISTRIB_ID] => Ubuntu
    [DISTRIB_RELEASE] => 13.04
    [DISTRIB_CODENAME] => raring
    [DISTRIB_DESCRIPTION] => Ubuntu 13.04
    [NAME] => Ubuntu
    [VERSION] => 13.04, Raring Ringtail
    [ID] => ubuntu
    [ID_LIKE] => debian
    [PRETTY_NAME] => Ubuntu 13.04
    [VERSION_ID] => 13.04
    [HOME_URL] => http://www.ubuntu.com/
    [SUPPORT_URL] => http://help.ubuntu.com/
    [BUG_REPORT_URL] => http://bugs.launchpad.net/ubuntu/
)
ID字段最适合确定分布,因为它是由Linux标准库定义的,并且应该存在于常见的发行版中。
顺便提一下,我建议不要使用exec()system()来读取文件,因为出于安全原因,它们在许多服务器上被禁用。(此外,这没有意义,因为PHP可以本地读取文件。如果它不能读取它们,那么也不可能通过系统调用实现。)

谢谢。您能否为函数“glob”添加一个网页链接,例如来自PHP手册?并且您为什么要使用它?与普通的文件/目录函数相比,有什么优势吗? - Sithu
你的代码出了问题。它发出了“500内部服务器错误”。 - Sithu
https://php.net/glob ... 500错误可能是由于新的数组语法引起的。我现在已经将其更改为旧的语法(PHP <5.4)。如果仍然无法正常工作,请检查实际错误消息的错误日志,或增加错误报告级别。 - lxg
是的,我的服务器上的PHP版本是5.3。现在它似乎可以工作了,但不幸的是它只输出一个空数组。请在这里检查。这个问题不是关于我的普通服务器,但结果相同。顺便说一下,这个链接运行在共享主机上,我发现exec()也可以工作。在这里检查 - Sithu
在Web IDE中,例如phpfiddle.org,exec()glob被禁用。 - Sithu
“exec” 在大多数主机上都被禁用了。然而,“glob” 在大多数主机上都是可用的;此外,许多常见的 PHP 应用程序也使用它。您可以直接检查上述文件是否存在,而不是使用“glob”。 - lxg

2

-1

(1) 由于重复的 cat,您的命令会返回错误。 (2) 查看我的答案,了解纯PHP解决方案。在这里使用 exec 是不好的,因为如果要保持可移植性,应该避免那些在许多主机上可能被禁用的函数。 - lxg
@lxg 没有返回错误,它确实起作用了,尽管是我的笔误。 - Sithu
@lxg 感谢您的回答,但是您的解决方案给了我500错误和没有输出。请看一下我在您的答案中的评论。根据我的经验,大多数情况下,在我的服务器上exec确实可以工作,可能是因为具有root访问权限的VPS。它可能无法在共享主机中工作,这是您所担心的。 - Sithu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接