プログラム内で OS の名前、バージョン、アーキテクチャを得る方法を調べてみた。アーキテクチャというのが実際になんなのかは微妙だが、まぁ主にプロセッサの種類ということにしよう。
いろいろ調べたのだが、まず簡単なのが 4.4BSD の類である。uname コマンドだけで、しかもオプションのうち、POSIX で定義されている -s, -r, -m, -v だけで済む。
FreeBSD:
uname -s : FreeBSD uname -r : 10.0-RELEASE uname -m : amd64 uname -v : FreeBSD 10.0-RELEASE #0 r260789: Thu Jan 16 22:34:59 UTC 2014 root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC
NetBSD:
uname -s : NetBSD uname -r : 6.1.3 uname -m : amd64 uname -v : NetBSD 6.1.3 (GENERIC)
OpenBSD:
uname -s : OpenBSD uname -r : 5.5 uname -m : amd64 uname -v : GENERIC#271
DragonFly BSD:
uname -s : DragonFly uname -r : 3.6-RELEASE uname -m : x86_64 uname -v : DragonFly v3.6.2-RELEASE #11: Wed Apr 9 19:27:24 PDT 2014 root@pkgbox64.dragonflybsd.org:/usr/obj/build/home/justin/src/sys/X86_64_GENERIC
uname -s が OS の名前、uname -r がバージョン、uname -m がアーキテクチャということでいいだろう。uname -v は OS の名前が入っていたりいなかったり長すぎたりして使いにくい。ただ、DragonFly のバージョンで最後の桁を得ようとすると uname -v をみる必要があるようだ。
uname はカーネルの情報を表示するものなので、カーネルと OS が一体として開発されているなら uname で済む。しかしそうでない場合、つまり GNU/Linux が典型例だが、OS の名前を得るには他の方法を使う必要がある。Debian などでは、Linux Standard Base (ISO/IEC 23360-1) で標準化されている lsb_release コマンドが使える。lsb_release コマンドにはいくつかオプションがあるが、ここでは "single line description of distribution" を short 形式で表示する -sd オプションを使う。Ubuntu は codename が出なくてちょっとさびしいので lsb_release -sc も使ってみよう。(なお、/etc/debian_version とかは際限がないので避けたい。lsb_release がなかったり、デフォルトではない GNU/Linux distribution があるというのも確かなんだけど。)
Debian GNU/Linux:
uname -s : Linux uname -r : 3.2.0-4-amd64 uname -m : x86_64 uname -v : #1 SMP Debian 3.2.57-3+deb7u2 lsb_release -sd : Debian GNU/Linux 7.5 (wheezy)
Ubuntu:
uname -s : Linux uname -r : 3.13.0-24-generic uname -m : x86_64 uname -v : #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 lsb_release -sd : Ubuntu 14.04 LTS lsb_release -sc : trusty
Fedora:
uname -s : Linux uname -r : 3.13.6-200.fc20.x86_64 uname -m : x86_64 uname -v : #1 SMP Fri Mar 7 17:02:28 UTC 2014 lsb_release -sd : "Fedora release 20 (Heisenbug)"
CentOS:
uname -s : Linux uname -r : 2.6.18-371.4.1.el5 uname -m : i686 uname -v : #1 SMP Thu Jan 30 06:09:24 EST 2014 lsb_release -sd : "CentOS release 5.10 (Final)"
RedHat 系の lsb_release -sd は結果を double quote で括るのがちょっといやらしいかな。
Slackware については lsb_release は見つからなかったが、systemd が推進している /etc/os-release というファイルがあった。
Slackware:
uname -s : Linux uname -r : 3.10.17-smp uname -m : i686 uname -v : #2 SMP Wed Oct 23 17:13:14 CDT 2013 $ cat /etc/os-release NAME=Slackware VERSION="14.1" ID=slackware VERSION_ID=14.1 PRETTY_NAME="Slackware 14.1" ANSI_COLOR="0;34" CPE_NAME="cpe:/o:slackware:slackware_linux:14.1" HOME_URL="http://slackware.com/" SUPPORT_URL="http://www.linuxquestions.org/questions/slackware-14/" BUG_REPORT_URL="http://www.linuxquestions.org/questions/slackware-14/"
ところで、Debian には Linux でないものがある。FreeBSD のカーネルを使った Debian GNU/kFreeBSD や Hurd を使った Debian GNU/Hurd である。Linux ではないのに、という気はするが、これらでも lsb_release コマンドが使える。
Debian GNU/kFreeBSD:
uname -s : GNU/kFreeBSD uname -r : 9.0-2-amd64 uname -m : x86_64 uname -v : #0 Sat Nov 24 04:44:27 UTC 2012 lsb_release -sd : Debian GNU/kFreeBSD 7.0 (wheezy)
Debian GNU/Hurd:
uname -s : GNU uname -r : 0.3 uname -m : i686-AT386 uname -v : GNU-Mach 1.3.99-486/Hurd-0.3 lsb_release -sd : Debian GNU 7.0 (wheezy)
GNU/Hurd じゃなくて単に GNU と出てくるのは、ユーザランドとカーネルが両方 GNU だから、かな。uname -m は i686-AT386 と他と比べて長くなっている。プロセッサだけじゃなくてマシンのアーキテクチャもついているのだろう。
他の OS もいくつか調べてみよう。
OpenIndiana (OpenSolaris の fork) の uname は SunOS と名乗って OpenIndiana という名前が出てこない。ここでは /etc/release の先頭行をみるのがよさそうである。バージョンは uname -v で、oi というのは OpenIndiana の略だろう。uname -m は i86pc という見慣れない名前で、見慣れた名前は uname -p (host's ISA or processor type) で出てくるようだ。
OpenIndiana:
uname -s : SunOS uname -r : 5.11 uname -m : i86pc uname -v : oi_151a7 uname -p : i386 head -1 /etc/release : OpenIndiana Development oi_151.1.7 X86 (powered by illumos)
Minix は uname で済む感じ。
Minix:
uname -s : Minix uname -r : 3.2.1 uname -m : i686 uname -v : 3.2.1
Haiku も uname で済むようだが、uname -v も見ないとバージョンは得られない感じか。
Haiku:
uname -s : Haiku uname -r : 1 uname -m : BePC uname -v : hrevr1alpha4-44702 Nov 14 2012
Mac OS X の uname では Mac OS X という名前が出てこない。ここでは sw_vers コマンドが使える。
Mac OS X:
uname -s : Darwin uname -r : 13.2.0 uname -m : x86_64 uname -v : Darwin Kernel Version 13.2.0: Thu Apr 17 23:03:13 PDT 2014; root:xnu-2422.100.13~1/RELEASE_X86_64 % sw_vers ProductName: Mac OS X ProductVersion: 10.9.3 BuildVersion: 13D65
AIX は uname でだいたいわかるようである。GCC Compile Farm にある AIX 7.1 で試したのだが、uname -v が operating system version で、uname -r が release number of the operating system ということなので、きっとこれらをつなげればいいのだろう。また、oslevel というコマンドもある。uname -m は machine ID number なるもので、アーキテクチャは uname -p で得られる。
AIX:
uname -s : AIX uname -r : 1 uname -m : 00F84C0C4C00 uname -v : 7 uname -p : powerpc oslevel : 7.1.0.0 oslevel -s : 7100-02-02-1316
最近、chkbuild のログを機械可読な形に変換するツールを作った。
<URL:https://github.com/nurse/rubyci/blob/master/lib/chkbuild-ruby-info.rb>
これで boron で昔からやっている chkbuild のログを変換して、ruby の trunk の test-all の failure の数 (error の数は含まない) の推移をプロットしてみた。(文字の位置はおおざっぱ)
まぁ、0 が定常状態になったのはタイミングからして rubyci.org と、それにともなってなるせさんがいろいろと言うようになったからですかねぇ。
元データも置いておく。
<URL:2014-06/chkbuild-boron-ruby-trunk.csv>
これはログを機械可読に変換した後、build というレコードだけぜんぶ取り出してまとめたものである。個々のテストの結果とか他のレコードもあるが、多いので除いてある。
lsb_release と /etc/os-release で、OS の名前とバージョンを得られるが、いくらか違う場合もある。
Debian:
% lsb_release -d Description: Debian GNU/Linux 7.5 (wheezy) % grep PRETTY_NAME /etc/os-release PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
Fedora:
% lsb_release -d Description: Fedora release 20 (Heisenbug) % grep PRETTY_NAME /etc/os-release PRETTY_NAME="Fedora 20 (Heisenbug)"
Gentoo:
% lsb_release -d Description: Gentoo Base System release 2.2 % grep PRETTY_NAME /etc/os-release PRETTY_NAME="Gentoo/Linux"
lsb_release のほうがいくらか詳細だが、これはいつでもそうなのだろうか。
[latest]