mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-19 21:34:53 +08:00
149 lines
4.6 KiB
PHP
149 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace StaticPHP\Util\System;
|
|
|
|
class LinuxUtil extends UnixUtil
|
|
{
|
|
/** @var null|string libc version cache */
|
|
public static ?string $libc_version = null;
|
|
|
|
/**
|
|
* Get current linux distro name and version.
|
|
*
|
|
* @noinspection PhpMissingBreakStatementInspection
|
|
* @return array{dist: string, ver: string} Linux distro info (unknown if not found)
|
|
*/
|
|
public static function getOSRelease(): array
|
|
{
|
|
$ret = [
|
|
'dist' => 'unknown',
|
|
'ver' => 'unknown',
|
|
];
|
|
switch (true) {
|
|
case file_exists('/etc/centos-release'):
|
|
$lines = file('/etc/centos-release');
|
|
$centos = true;
|
|
goto rh;
|
|
case file_exists('/etc/redhat-release'):
|
|
$lines = file('/etc/redhat-release');
|
|
$centos = false;
|
|
rh:
|
|
foreach ($lines as $line) {
|
|
if (preg_match('/release\s+(\d*(\.\d+)*)/', $line, $matches)) {
|
|
/* @phpstan-ignore-next-line */
|
|
$ret['dist'] = $centos ? 'centos' : 'redhat';
|
|
$ret['ver'] = $matches[1];
|
|
}
|
|
}
|
|
break;
|
|
case file_exists('/etc/os-release'):
|
|
$lines = file('/etc/os-release');
|
|
foreach ($lines as $line) {
|
|
if (preg_match('/^ID=(.*)$/', $line, $matches)) {
|
|
$ret['dist'] = $matches[1];
|
|
}
|
|
if (preg_match('/^VERSION_ID=(.*)$/', $line, $matches)) {
|
|
$ret['ver'] = $matches[1];
|
|
}
|
|
}
|
|
$ret['dist'] = trim($ret['dist'], '"\'');
|
|
$ret['ver'] = trim($ret['ver'], '"\'');
|
|
if (strcasecmp($ret['dist'], 'centos') === 0) {
|
|
$ret['dist'] = 'redhat';
|
|
}
|
|
break;
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* Check if current linux distro is musl-based (alpine).
|
|
*/
|
|
public static function isMuslDist(): bool
|
|
{
|
|
return static::getOSRelease()['dist'] === 'alpine';
|
|
}
|
|
|
|
/**
|
|
* Get CPU core count.
|
|
*/
|
|
public static function getCpuCount(): int
|
|
{
|
|
$ncpu = 1;
|
|
|
|
if (is_file('/proc/cpuinfo')) {
|
|
$cpuinfo = file_get_contents('/proc/cpuinfo');
|
|
preg_match_all('/^processor/m', $cpuinfo, $matches);
|
|
$ncpu = count($matches[0]);
|
|
}
|
|
|
|
return $ncpu;
|
|
}
|
|
|
|
/**
|
|
* Get fully-supported linux distros.
|
|
*
|
|
* @return string[] List of supported Linux distro name for doctor
|
|
*/
|
|
public static function getSupportedDistros(): array
|
|
{
|
|
return [
|
|
// debian-like
|
|
'debian', 'ubuntu', 'Deepin',
|
|
// rhel-like
|
|
'redhat',
|
|
// centos
|
|
'centos',
|
|
// alpine
|
|
'alpine',
|
|
// arch
|
|
'arch', 'manjaro',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get libc version string from ldd.
|
|
*/
|
|
public static function getLibcVersionIfExists(?string $libc = null): ?string
|
|
{
|
|
if (self::$libc_version !== null) {
|
|
return self::$libc_version;
|
|
}
|
|
if ($libc === 'glibc') {
|
|
$result = shell()->execWithResult('ldd --version', false);
|
|
if ($result[0] !== 0) {
|
|
return null;
|
|
}
|
|
// get first line
|
|
$first_line = $result[1][0];
|
|
// match ldd version: "ldd (some useless text) 2.17" match 2.17
|
|
$pattern = '/ldd\s+\(.*?\)\s+(\d+\.\d+)/';
|
|
if (preg_match($pattern, $first_line, $matches)) {
|
|
self::$libc_version = $matches[1];
|
|
return self::$libc_version;
|
|
}
|
|
return null;
|
|
}
|
|
if ($libc === 'musl') {
|
|
if (self::isMuslDist()) {
|
|
$result = shell()->execWithResult('ldd 2>&1', false);
|
|
} elseif (is_file('/usr/local/musl/lib/libc.so')) {
|
|
$result = shell()->execWithResult('/usr/local/musl/lib/libc.so 2>&1', false);
|
|
} else {
|
|
$arch = php_uname('m');
|
|
$result = shell()->execWithResult("/lib/ld-musl-{$arch}.so.1 2>&1", false);
|
|
}
|
|
// Match Version * line
|
|
// match ldd version: "Version 1.2.3" match 1.2.3
|
|
$pattern = '/Version\s+(\d+\.\d+\.\d+)/';
|
|
if (preg_match($pattern, $result[1][1] ?? '', $matches)) {
|
|
self::$libc_version = $matches[1];
|
|
return self::$libc_version;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|