Linuxディストリビューションの種類やバージョンを確認する

# 1. はじめに

Linuxには数多くのディストリビューションがある。企業系システムで使うものは限られるが、それでもいくつかの種類がある。ディストリビューションによって判定方法が少し異なるので、主要ディストリビューションについて調査した。

※当初はクラウドごとの違いも調べようと考えていたが、クラウドに依存する部分はなかった。

### 1-1. モチベーション&対象読者

* Linuxディストリビューションの判定方法が、ディストリビューションによって異なる
* ディストリビューションを調査し、共通の判別方法を調べる

### 1-2. 対象環境

* RHEL系Linux OS(RHEL, CentOS, CentOS Stream, Amazon Linux, Oracle Linux, etc)
* Ubuntu
* オンプレミス＆クラウド

# 2. ディストリビューション判別の基本

Linuxディストリビューションの種類を判別する基本は`/etc/*release`ファイルを確認することだ。代表的なものとしては以下のファイルがある。

- **ディストリビューション共通**
  - /etc/os-release
  - /etc/system-release
- **ディストリビューション固有**
  - /etc/redhat-release
  - /etc/centos-release
  - /etc/oracle-release

たとえばCentOSであれば`/etc/centos-release`を見ればよい。次のように表示されれば、CentOS 8.1であることがわかる。

```:/etc/centos-release
CentOS Linux release 8.1.1911 (Core)
```

ところがCentOS以外には`/etc/centos-release`はない。そのためディストリビューションに合わせて参照するファイルを変更する必要がある。また`/etc/os-release`や`/etc/system-release`はディストリビューション非依存のファイルだが一貫性はない。

# 3. 各ディストリビューション調査

今回は以下のディストリビューションについて調査する。RHEL系は8をベースにしているが、6でも7でも基本的には同じである。

* Red Hat Enterprise Linux
* CentOS / CentOS Stream
* Oracle Linux
* Amazon Linux
* Ubuntu

### 3-1. Red Hat Enterprise Linux
3つのファイルがあり、`/etc/system-release`は`/etc/redhat-release`のシンボリックリンクになっている。

```shell-session
$ ls -l /etc/*release
lrwxrwxrwx. 1 root root 22 Mar 31 07:15 /etc/os-release -> ..//usr/lib/os-release
-rw-r--r--. 1 root root 45 Mar 31 07:15 /etc/redhat-release
lrwxrwxrwx. 1 root root 14 Mar 31 07:15 /etc/system-release -> redhat-release
```

```shell-session
$ cat /etc/redhat-release
Red Hat Enterprise Linux release 8.2 (Ootpa)
```

```shell-session
$ cat /etc/os-release
NAME="Red Hat Enterprise Linux"
VERSION="8.2 (Ootpa)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="8.2"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Red Hat Enterprise Linux 8.2 (Ootpa)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:8.2:GA"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"

REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_BUGZILLA_PRODUCT_VERSION=8.2
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.2"
```

### 3-2. CentOS/CentOS Stream

CentOS/CentOS Streamでは`/etc/system-release`や`/etc/redhat-release`が`/etc/centos-release`へのシンボリックリンクになっている。

```shell-session
$ ls -l /etc/*release
-rw-r--r--. 1 root root 38  3月 13 04:15 /etc/centos-release
lrwxrwxrwx. 1 root root 21  3月 13 04:15 /etc/os-release -> ../usr/lib/os-release
lrwxrwxrwx. 1 root root 14  3月 13 04:15 /etc/redhat-release -> centos-release
lrwxrwxrwx. 1 root root 14  3月 13 04:15 /etc/system-release -> centos-release
```

```shell-session:CentOS8
$ cat /etc/centos-release
CentOS Linux release 8.1.1911 (Core)
```

```shell-session:CentOS8Stream
$ cat /etc/centos-release
CentOS Stream release 8
```

```shell-session:CentOS8
$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="8 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="8"
```

```shell-session:CentOS8Stream
$ cat /etc/os-release
NAME="CentOS Stream"
VERSION="8"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Stream 8"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_SUPPORT_PRODUCT_VERSION="CentOS Stream"
```

<font color="blue">**ヒント**</font>
<font color="blue">　RHEL系ディストリビューションの多くは、8.1や8.2の小数点一桁はあまり気にする必要はない。なぜならば、たとえ8.1のイメージ（メディア）でも、Yum/DNFでアップデートすれば、その時点の最新と同じになるからだ。
　このあたりはリポジトリの設定もかかわってくるのだが、話が深くなるので興味のあるかたは自分で調べてほしい。</font>


### 3-3. Oracle Linux

Oracle Linuxでは`/etc/oracle-release`が追加されている。

```shell-session
$ ls -l /etc/*release
-rw-r--r--. 1 root root  32 May  5 02:08 /etc/oracle-release
-rw-r--r--. 1 root root 479 May  5 02:08 /etc/os-release
-rw-r--r--. 1 root root  45 May  5 02:08 /etc/redhat-release
lrwxrwxrwx. 1 root root  14 May  5 02:08 /etc/system-release -> oracle-release
```

興味深いのはCentOSとの比較だろう。CentOSでは`/etc/redhat-release`はシンボリックリンクなのに対し、Oracle Linuxではシンボリックリンクになっていない。

```shell-session
$ cat /etc/oracle-release
Oracle Linux Server release 8.2
```

```shell-session
$ cat /etc/os-release
NAME="Oracle Linux Server"
VERSION="8.2"
ID="ol"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="8.2"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Oracle Linux Server 8.2"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:oracle:linux:8:2:server"
HOME_URL="https://linux.oracle.com/"
BUG_REPORT_URL="https://bugzilla.oracle.com/"

ORACLE_BUGZILLA_PRODUCT="Oracle Linux 8"
ORACLE_BUGZILLA_PRODUCT_VERSION=8.2
ORACLE_SUPPORT_PRODUCT="Oracle Linux"
ORACLE_SUPPORT_PRODUCT_VERSION=8.2
```

`/etc/redhat-release`はシンボリックリンクではないので、次のようにRHELと同じになっている。

```shell-session
$ cat /etc/redhat-release
Red Hat Enterprise Linux release 8.2 (Ootpa)
```

このような仕様になっているのは、ディストリビューションをチェックするプログラムに対する互換性対策だろう。

商用製品やHWベンダーが提供しているドライバ類のパッケージには`/etc/*-release`を使ってディストリビューションの種類やバージョンを判定していることが多い。オリジナルの`/etc/redhat-release`を残すことで、RHELと誤認識させてチェックをすり抜けることができる。


```shell-session:バージョン判定の擬似コード
if /etc/redhat-releaseがあるか
　バージョン確認
else if /etc/centos-releaseがあるか
  バージョン確認
```
### 3-4. Amazon Linux 2

Amazon Linux 2には`/etc/＜ディストリビューション名＞-release`のようなファイルはない。

```shell-session
$ ls -l /etc/*release
-rw-r--r-- 1 root root 212 Jun 24 21:10 /etc/os-release
-rw-r--r-- 1 root root  31 Jun 24 21:10 /etc/system-release
```

```shell-session
$ cat /etc/system-release
Amazon Linux release 2 (Karoo)
```

Amazon LinuxはRHEL系ディストリビューションだが、CentOSやOracle Linuxとは異なり、ピュアなRHEL互換ディストリビューションではない。そのため`/etc/os-release`の内容も、他のRHEL系ディストリビューションとは異なる。

```shell-session
$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
```

### 3-5. Ubuntu

Ubuntuでは次のファイルがある。今回20.04 LTSを使用しているが、18.04 LTSも基本的には同じだ。

```shell-session
$ ls -l /etc/*release
-rw-r--r-- 1 root root 102 Apr 15 11:09 /etc/lsb-release
lrwxrwxrwx 1 root root  21 Apr 15 11:09 /etc/os-release -> ../usr/lib/os-release

$ ls -l /etc/*version
-rw-r--r-- 1 root root 13 Dec  5  2019 /etc/debian_version
-rw-r--r-- 1 root root 31 Jul 14 15:46 /etc/ec2_version
```

```shell-session
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```

Ubuntuでは`/etc/lsb-release`や`lsb_release -a`コマンドを使うことが多い。RHEL系ディストリビューションにも`lsb_release`コマンドはあるが、デフォルトインストールされていないことが多い（redhat-lsb-coreパッケージ）。

```shell-session
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04 LTS"

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04 LTS
Release:        20.04
Codename:       focal
```

```shell-session
20.04 LTSのとき
$ cat /etc/debian_version
bullseye/sid

18.04 LTSのとき
$ cat /etc/debian_version
buster/sid
```

ec2というとAmazon EC2固有のものに感じるが、Azure VMやOracle Cloud Infrastructure Computeにもあった。

```shell-session
$ cat /etc/ec2_version
Ubuntu 20.04 LTS (Focal Fossa)
```

### 3-6. おまけ（サンプルコード）

ディストリビューションの種類とバージョンを判定するシェルスクリプトのサンプルコードを紹介する。sedを使ってもいいだろう。

```shell-session
#!/bin/bash
FILENAME=/etc/os-release
dist=`grep -e ^NAME= ${FILENAME}`
dist=${dist#*\"}
dist=${dist%*\"}
echo "DIST: " $dist

version=`grep -e ^VERSION_ID= ${FILENAME}`
version=${version#*\"}
version=${version%*\"}
version=${version%*\.*}   # マイナーバージョン削除
echo "VER: " $version
```

```:出力結果
DIST:  Oracle Linux Server
VER:  8
```

# 4. まとめ

* **ディストリビューションの種類やバージョンを調べるには`/etc/*release`を使用する**
* **ディストリビューション共通のファイルとしては`/etc/os-release`が使える**