47
How to Parse /etc/os-release
As part of my daily tasks, I need to parse the /etc/os-release file for information using Python. I have seen various attempts from other people, most of which are too complicated, too cumbersome, so I came up with my own.
Below is a sample contents.
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 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
The easiest way to parse this file is to you the PyYAML library. However, in some projects, my team does not have access to third-party libraries and have to stay within the Python 3.7's standard libraries.
After several attempts, I came up with a fairly easy solution: Use the csv
library. Below is a code snippet which parses /etc/os-release and returns a dictionary.
import csv
import pathlib
from pprint import pprint
path = pathlib.Path("/etc/os-release")
with open(path) as stream:
reader = csv.reader(stream, delimiter="=")
os_release = dict(reader)
pprint(os_release)
Here is the output:
{'BUG_REPORT_URL': 'https://bugs.launchpad.net/ubuntu/',
'HOME_URL': 'https://www.ubuntu.com/',
'ID': 'ubuntu',
'ID_LIKE': 'debian',
'NAME': 'Ubuntu',
'PRETTY_NAME': 'Ubuntu 20.04.3 LTS',
'PRIVACY_POLICY_URL': 'https://www.ubuntu.com/legal/terms-and-policies/privacy-policy',
'SUPPORT_URL': 'https://help.ubuntu.com/',
'UBUNTU_CODENAME': 'focal',
'VERSION': '20.04.3 LTS (Focal Fossa)',
'VERSION_CODENAME': 'focal',
'VERSION_ID': '20.04'}
- The file contains lines of key=value, so I use the
csv
library to read it and specify the equal sign as fields delimiters. - The
reader
will yield a list of (key, value) tuples - The
dict
built-in turns that list of tuples into a dictionary
After several attempts, I like this solution the best because it leaves the parsing to a standard library, which I assume well tested.
47