Created
October 27, 2017 08:43
-
-
Save aras-p/47e2252d6b1fa57d3619fd8e021690ec to your computer and use it in GitHub Desktop.
Perl get hardware/OS data without non-standard modules
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
BEGIN { | |
if ($^O eq "MSWin32") | |
{ | |
require Win32; Win32::->import(); | |
require Win32::API; Win32::API::->import(); | |
require Win32::TieRegistry; Win32::TieRegistry::->import(); | |
} | |
} | |
use List::Util 'first'; | |
my $cpu = 'Unknown'; | |
my $cpus = 0; | |
my $cpufreq = 0; | |
my $ram = 0; | |
my $os = 'Unknown'; | |
sub trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s }; | |
if ($^O eq "MSWin32") | |
{ | |
# 0.09s | |
# Note: could use "wmic" to query that stuff, but that is a bit slower (e.g. whole sysinfo.pl script takes 0.38s) | |
# | |
# OS: 'Windows 10.0.15063' | |
# CPU: 'Intel(R) Core(TM) i7-5820K CPU @ 3.30GHz' | |
# CPU count: 12 | |
# CPU freq: 3.3 GHz | |
# RAM: 16 GB | |
$cpus = $ENV{'NUMBER_OF_PROCESSORS'}; | |
my $cpuKey = $Registry->Open( "LMachine/HARDWARE/DESCRIPTION/System/CentralProcessor/0", {Access=>Win32::TieRegistry::KEY_READ(),Delimiter=>"/"} ); | |
if ($cpuKey) | |
{ | |
$cpu = $cpuKey->{"/ProcessorNameString"}; | |
$cpufreq = hex($cpuKey->{"/~MHz"}); | |
$cpufreq = int(($cpufreq + 50) / 100) * 100; # round to hundreds of MHz | |
} | |
Win32::API::Struct->typedef( | |
MEMORYSTATUSEX => qw{ | |
DWORD dwLength; | |
DWORD MemLoad; | |
ULONGLONG TotalPhys; | |
ULONGLONG AvailPhys; | |
ULONGLONG TotalPage; | |
ULONGLONG AvailPage; | |
ULONGLONG TotalVirtual; | |
ULONGLONG AvailVirtual; | |
ULONGLONG AvailExtendedVirtual; | |
} | |
); | |
if (Win32::API->Import('kernel32', 'BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpMemoryStatusEx)')) | |
{ | |
my $memstatus = Win32::API::Struct->new('MEMORYSTATUSEX'); | |
$memstatus->{dwLength} = $memstatus->sizeof(); | |
$memstatus->{MemLoad} = 0; | |
$memstatus->{TotalPhys} = 0; | |
$memstatus->{AvailPhys} = 0; | |
$memstatus->{TotalPage} = 0; | |
$memstatus->{AvailPage} = 0; | |
$memstatus->{TotalVirtual} = 0; | |
$memstatus->{AvailVirtual} = 0; | |
$memstatus->{AvailExtendedVirtual} = 0; | |
GlobalMemoryStatusEx($memstatus); | |
$ram = $memstatus->{TotalPhys}; | |
} | |
($osString, $osMajor, $osMinor, $osBuild, $osID) = Win32::GetOSVersion(); | |
$os = "Windows $osMajor.$osMinor.$osBuild"; | |
} | |
elsif ($^O eq 'darwin') | |
{ | |
# 0.03s | |
# OS: 'macOS 10.12.6' | |
# CPU: 'Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz' | |
# CPU count: 8 | |
# CPU freq: 2.3 GHz | |
# RAM: 16 GB | |
$os = 'macOS Unknown'; | |
my $strOS = trim(scalar(`sw_vers`)); | |
$os = 'macOS ' . $1 if $strOS =~ /ProductVersion:\s*(.+)/; | |
$cpu = trim(`sysctl -n machdep.cpu.brand_string`); | |
$cpus = trim(`sysctl -n hw.ncpu`); | |
$cpufreq = trim(`sysctl -n hw.cpufrequency`) / 1000000.0; | |
$ram = trim(`sysctl -n hw.memsize`); | |
} | |
else | |
{ | |
# 0.03s | |
# OS: 'Linux Ubuntu 16.04.2 LTS' | |
# CPU: 'Intel(R) Core(TM) i7-5820K CPU @ 3.30GHz' | |
# CPU count: 12 | |
# CPU freq: 3.301 GHz | |
# RAM: 16 GB | |
open my $h, "/proc/cpuinfo"; | |
if ($h) | |
{ | |
my @info = <$h>; | |
close $h; | |
$cpus = scalar(map /^processor/, @info); | |
my $strCPU = first { /^model name/ } @info; | |
$cpu = $1 if ($strCPU && $strCPU =~ /:\s+(.*)/); | |
my $strFreq = first { /^cpu MHz/ } @info; | |
$cpufreq = $1 if ($strFreq && $strFreq =~ /:\s+(.*)/); | |
} | |
open $h, "/proc/meminfo"; | |
if ($h) | |
{ | |
my @info = <$h>; | |
close $h; | |
my $strRAM = first { /^MemTotal/ } @info; | |
$ram = $1 * 1024 if ($strRAM && $strRAM =~ /:\s+(\d+)/); | |
} | |
$os = 'Linux Unknown'; | |
open $h, "/etc/lsb-release"; | |
if ($h) | |
{ | |
my @info = <$h>; | |
close $h; | |
my $strOS = first { /^DISTRIB_DESCRIPTION/ } @info; | |
$os = 'Linux ' . $1 if ($strOS && $strOS =~ /=\"(.*)\"/); | |
} | |
} | |
$ram = int($ram / 1024 / 1024 / 1024 + 0.5); | |
$cpufreq = int($cpufreq) / 1000; | |
print "OS: '$os'\n"; | |
print "CPU: '$cpu'\n"; | |
print "CPU count: $cpus\n"; | |
print "CPU freq: $cpufreq GHz\n"; | |
print "RAM: $ram GB\n"; |
@davestoddard very much likely, all I care for my case is Windows, Mac & Linux. I don't have any FreeBSD environment here to test whether whatever I'd write up would actually work.
Thanks for the gist. Can you provide a license for it? (E.g. MIT)
Thanks for the gist. Can you provide a license for it? (E.g. MIT)
@nilsoberg2 I'm fine with unlicense / public domain
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is no allowance for FreeBSD here. The best way to collect this data would be through the FreeBSD sysctl subsystem. CPU is available via 'sysctl hw.model', OS is 'sysctl kern.ostype', CPU count is 'sysctl kern.smp.cpus', CPU frequency is 'sysctl machdep.tsc_freq', and RAM is 'sysctl kern.ipc.maxmbufmem'.