I've got a python script that uses sys.platform.startswith('linux') to test if it is on linux or not, but then I can't tell the difference between the x86/64 processor, and the raspberry pi's ARM processor.
The reason I need this, is to run an external script that's compiled for either mac, linux x86/64, or linux ARM for the raspberry pi.
From what I can tell, there's not really a unified way to tell that you are in fact running on a raspberry pi. Any help would be appreciated.
-
1Can you use os.uname() to obtain this information?milancurcic– milancurcic2013年02月24日 17:12:27 +00:00Commented Feb 24, 2013 at 17:12
-
Will that work on all distros for raspberry pi? On raspbian wheezy, it seems to work.jnesselr– jnesselr2013年02月24日 17:30:37 +00:00Commented Feb 24, 2013 at 17:30
10 Answers 10
You can use Python's os
module to obtain this information through uname
:
import os
os.uname()
This function should provide platform and other information on most Linux or Unix-like distributions.
From the Python documentation:
os.uname()
Return a 5-tuple containing information identifying the current operating system. The tuple contains five strings: (sysname, nodename, release, version, machine). Some systems truncate the nodename to eight characters or to the leading component; a better way to get the hostname is
socket.gethostname()
or evensocket.gethostbyaddr(socket.gethostname())
.Availability: recent flavors of Unix.
-
4
os.uname()[4][:3] == 'arm'
OrangeTux– OrangeTux2013年07月06日 13:09:10 +00:00Commented Jul 6, 2013 at 13:09 -
2Anyone who looks at this now, we ended up doing os.uname()[4].startsWith("arm") to check.jnesselr– jnesselr2014年01月26日 07:27:36 +00:00Commented Jan 26, 2014 at 7:27
-
2@jnesselr tiny typo, it is
startswith
, notstartsWith
. Thanks, it helped.Nishant– Nishant2014年10月04日 09:49:13 +00:00Commented Oct 4, 2014 at 9:49 -
4Not every ARM-based computer is a Raspberry Pi.scai– scai2021年01月02日 20:15:34 +00:00Commented Jan 2, 2021 at 20:15
-
I want to second @scai. Newer models of Apple's Mac computers now run Arm chips: en.wikipedia.org/wiki/Apple_M1 hence
os.uname()[4][:3] == 'arm'
will yield True for both Raspberry Pi and for any Apple computer with an M1 chip.dtadres– dtadres2022年11月28日 05:01:37 +00:00Commented Nov 28, 2022 at 5:01
I found you can get the Pi model and version from:
/sys/firmware/devicetree/base/model
Ex: Raspberry Pi 3 Model B Rev 1.2
I have a shell script to look for this and return the contents if it exists. An OS call to read the file if it exists should set you right. The premise is, if it doesn't exist, its definitely not a RPi. If it does, then inspect the content to be sure.
Here is a simplified version of @Artur Barseghyan's answer
import io
import os
def is_raspberrypi():
if os.name != 'posix':
return False
chips = ('BCM2708','BCM2709','BCM2711','BCM2835','BCM2836')
try:
with io.open('/proc/cpuinfo', 'r') as cpuinfo:
for line in cpuinfo:
if line.startswith('Hardware'):
_, value = line.strip().split(':', 1)
value = value.strip()
if value in chips:
return True
except Exception:
pass
return False
Or for an even leaner solution as suggested by @Dougie without the need to maintain an updated list of chipsets.
def is_raspberrypi():
try:
with io.open('/sys/firmware/devicetree/base/model', 'r') as m:
if 'raspberry pi' in m.read().lower(): return True
except Exception: pass
return False
platform.machine()
will return:
armv7l
on Raspberry Pi running on Raspbian 32-bit.aarch64
on all Arm 64-bit OSes, including those running in Amazon AWS Graviton2.
So this is a more reliable way of detecting Arm, if your program is written for Arm, instead of Raspberry Pi specifically.
-
+1 as you can use this with PEP 508 in requirements.txt filesD. LaRocque– D. LaRocque2022年02月02日 01:56:02 +00:00Commented Feb 2, 2022 at 1:56
This is more of a problem with the advent of the Pi 2 (which is not simple to distinguish from the Beaglebone Black). The highest level of detail is found in /proc/cpuinfo on Linux-based systems (the 'Hardware' line). Here's an example of parsing that, from the Adafruit GPIO code:
https://github.com/adafruit/Adafruit_Python_GPIO/blob/master/Adafruit_GPIO/Platform.py
-
1This sounds like the best answer to me, since I would have suggested testing /proc/cpuinfo. I've never seen the platform.py from adafruit before, but looking over it, it makes sense. Also if the file doesn't exist, you'll know it's not a linux based system. Thanks for this :). Have my +1.Peter– Peter2015年02月18日 04:35:13 +00:00Commented Feb 18, 2015 at 4:35
-
I encountered this yesterday when trying to get py-gaugette working with my Pi2... it (currently) uses the platform module method that unfortunately fails with the Pi2 and will hopefully benefit from this as well. github.com/guyc/py-gaugette/issues/12MartyMacGyver– MartyMacGyver2015年02月18日 07:30:37 +00:00Commented Feb 18, 2015 at 7:30
The best widely-applicable system-identifying information I have found has been with:
platform._syscmd_uname('-a')
This appears to give the same output as the shell command uname -a
. In most cases the returned output is essentially the same (a string instead of a 5-tuple) as that of os.uname()
.
The ones I've tested and found equivalent outputs are OSX 10.9.5, Ubuntu 14.04, and Raspbian (??) Wheezy. On a Synology NAS, though, I get more information from the platform._syscmd_uname('-a')
version:
>>> os.uname()
('Linux', [hostname], '3.10.35', [...], 'x86_64')
>>> platform._syscmd_uname('-a')
'Linux [hostname] 3.10.35 [...] x86_64 GNU/Linux synology_cedarview_1813+'
Seeing "synology" in the output there identifies it as an environment where things behave unexpectedly.
Better way of doing this (Python code snippet):
import io
def is_raspberry_pi(raise_on_errors=False):
"""Checks if Raspberry PI.
:return:
"""
try:
with io.open('/proc/cpuinfo', 'r') as cpuinfo:
found = False
for line in cpuinfo:
if line.startswith('Hardware'):
found = True
label, value = line.strip().split(':', 1)
value = value.strip()
if value not in (
'BCM2708',
'BCM2709',
'BCM2711',
'BCM2835',
'BCM2836'
):
if raise_on_errors:
raise ValueError(
'This system does not appear to be a '
'Raspberry Pi.'
)
else:
return False
if not found:
if raise_on_errors:
raise ValueError(
'Unable to determine if this system is a Raspberry Pi.'
)
else:
return False
except IOError:
if raise_on_errors:
raise ValueError('Unable to open `/proc/cpuinfo`.')
else:
return False
return True
IS_RASPBERRY_PI = is_raspberry_pi()
-
2Why not read the Raspberry Pi model with
cat /sys/firmware/devicetree/base/model;echo
and save a bunch of pain. You can do that with two lines of python code.Dougie– Dougie2020年11月19日 22:17:12 +00:00Commented Nov 19, 2020 at 22:17 -
@Dougie can you share those two lines of python code? I condensed this answer best I could in my answer for a cross platform solution but if there is a shorter route I'd take that.Chris– Chris2020年11月20日 23:05:46 +00:00Commented Nov 20, 2020 at 23:05
-
#!/usr/bin/python3 with open('/sys/firmware/devicetree/base/model') as model: RPi_model = model.read() print (RPi_model)
Dougie– Dougie2020年11月20日 23:17:23 +00:00Commented Nov 20, 2020 at 23:17 -
1Thanks @Dougie. Updated my answer with your solution.Chris– Chris2020年11月20日 23:57:02 +00:00Commented Nov 20, 2020 at 23:57
I've used this simple function previously:
from pathlib import Path
import re
CPUINFO_PATH = Path("/proc/cpuinfo")
def is_raspberry_pi():
if not CPUINFO_PATH.exists():
return False
with open(CPUINFO_PATH) as f:
cpuinfo = f.read()
return re.search(r"^Model\s*:\s*Raspberry Pi", cpuinfo, flags=re.M) is not None
It just checks that the /proc/cpuinfo
file exists, and then checks if there is a Model line that matches Raspberry Pi.
It might not be completely generic, but it does not rely on BCM-processor being used exclusively for Raspberry Pi:s, nor arm, so it should give very few false positives, but possibly risks to return some false negatives in case Raspberry Pi OS changes the cpuinfo.
Tested on Raspberry Pi 4 and Raspberry Pi 3B.
-
Why not use
platform.machine()
that gives you the CPU architecture, and that was the OPs question.MatsK– MatsK2022年10月28日 09:08:47 +00:00Commented Oct 28, 2022 at 9:08 -
1In OPs case, that would suffice since the external dependencies were compiled specifically for the ARM-architecture. But if you also rely on some Python libraries that are specific for the Pi, but not ARM, then using the above can be more accurate.Erasmus Cedernaes– Erasmus Cedernaes2022年10月29日 10:12:58 +00:00Commented Oct 29, 2022 at 10:12
You can simply check if the file /etc/rpi-issue
exists with pathlib
.
from pathlib import Path
IS_RPI = Path("/etc/rpi-issue").exists()
I know the file can be created easily but every raspberyOS and Raspbian has that file.
-
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.2022年12月18日 12:07:22 +00:00Commented Dec 18, 2022 at 12:07
On PI 3
import os
os.uname()[1] == 'raspberrypi'
Because:
uname -a
Linux raspberrypi 4.4.50-v7+ #970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l GNU/Linux
-
12'raspberrypi' your hostname - this won't work if you change the hostname to something elserhu– rhu2017年07月19日 16:08:40 +00:00Commented Jul 19, 2017 at 16:08