Detecta que un programa de Python se está ejecutando en la pi

23

Tengo un script de Python que usa sys.platform.startswith ('linux') para probar si está en linux o no, pero luego no puedo distinguir la diferencia entre el procesador x86 / 64 y el ARM de la frambuesa pi procesador.

La razón por la que necesito esto es para ejecutar un script externo que se compila para mac, linux x86 / 64 o linux ARM para la frambuesa pi.

Por lo que puedo decir, en realidad no hay una forma unificada de decir que de hecho estás ejecutando un raspberry pi. Cualquier ayuda sería apreciada.

jnesselr
fuente
1
¿Puedes usar os.uname () para obtener esta información?
milancurcic
¿Funcionará en todas las distribuciones de raspberry pi? En raspbian wheezy, parece funcionar.
jnesselr

Respuestas:

12

Puede usar el osmódulo de Python para obtener esta información a través de uname:

import os
os.uname()

Esta función debe proporcionar información sobre la plataforma y otra información sobre la mayoría de las distribuciones similares a Linux o Unix.

De la documentación de Python:

os.uname ()

Devuelve una tupla de 5 tuplas que contiene información que identifica el sistema operativo actual. La tupla contiene cinco cadenas: (sysname, nodename, release, version, machine). Algunos sistemas truncan el nombre de nodo a ocho caracteres o al componente principal; una mejor manera de obtener el nombre de host es socket.gethostname()o incluso socket.gethostbyaddr(socket.gethostname()).

Disponibilidad: sabores recientes de Unix.

milancurcic
fuente
2
os.uname()[4][:3] == 'arm'
OrangeTux
2
Cualquiera que mire esto ahora, terminamos haciendo os.uname () [4] .startsWith ("arm") para verificar.
jnesselr
2
@jnesselr pequeña errata, es startswith, no startsWith. Gracias, me ayudó.
Nishant
5

Descubrí que puedes obtener el modelo y la versión Pi de:

/ sys / firmware / devicetree / base / model

Ej: Raspberry Pi 3 Modelo B Rev 1.2

Tengo un script de shell para buscar esto y devolver el contenido si existe. Una llamada del sistema operativo para leer el archivo, si existe, debería hacerlo bien. La premisa es que, si no existe, definitivamente no es un RPi. Si es así, inspeccione el contenido para asegurarse.

Wesley Mason
fuente
3

Esto es más un problema con la llegada del Pi 2 (que no es fácil de distinguir del Beaglebone Black). El nivel más alto de detalle se encuentra en / proc / cpuinfo en sistemas basados ​​en Linux (la línea 'Hardware'). Aquí hay un ejemplo de análisis que, desde el código Adafruit GPIO:

https://github.com/adafruit/Adafruit_Python_GPIO/blob/master/Adafruit_GPIO/Platform.py

MartyMacGyver
fuente
1
Esto me parece la mejor respuesta, ya que habría sugerido probar / proc / cpuinfo. Nunca he visto la plataforma .py de adafruit antes, pero mirarla tiene sentido. Además, si el archivo no existe, sabrá que no es un sistema basado en Linux. Gracias por esto :). Tener mi +1.
Peter
Encontré esto ayer cuando intentaba que py-gaugette funcionara con mi Pi2 ... (actualmente) usa el método del módulo de plataforma que desafortunadamente falla con el Pi2 y espero que también se beneficie de esto. github.com/guyc/py-gaugette/issues/12
MartyMacGyver
3

La mejor información de identificación del sistema ampliamente aplicable que he encontrado ha sido con:

platform._syscmd_uname('-a')

Esto parece dar el mismo resultado que el comando de shell uname -a. En la mayoría de los casos, la salida devuelta es esencialmente la misma (una cadena en lugar de una tupla de 5) que la de os.uname().

Los que probé y encontré salidas equivalentes son OSX 10.9.5, Ubuntu 14.04 y Raspbian (??) Wheezy. Sin embargo, en un NAS de Synology, obtengo más información de la platform._syscmd_uname('-a')versión:

>>> 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+'

Ver "synology" en la salida lo identifica como un entorno donde las cosas se comportan inesperadamente.

Brock Mendel
fuente
1

Mejor forma de hacerlo ( fragmento de código de Python ):

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',
                        '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()
Artur Barseghyan
fuente
-1

En PI 3

import os    
os.uname()[1] == 'raspberrypi'

Porque:

uname -a
Linux raspberrypi 4.4.50-v7+ #970 SMP Mon Feb 20 19:18:29 GMT 2017 armv7l GNU/Linux
Grzegorz Głowacki
fuente
8
'raspberrypi' su nombre de host - esto no funcionará si cambia el nombre de host a otra cosa
rhu