Skip to content

Instantly share code, notes, and snippets.

@hlecuanda
Last active March 20, 2019 05:26
Show Gist options
  • Save hlecuanda/a403f94ab24b933f4bf2844d2b15e8c5 to your computer and use it in GitHub Desktop.
Save hlecuanda/a403f94ab24b933f4bf2844d2b15e8c5 to your computer and use it in GitHub Desktop.
Explorando el Sistema con Python 3
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Explorando el Sistema con Python 3",
"version": "0.3.2",
"provenance": [],
"collapsed_sections": [],
"toc_visible": true,
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/hlecuanda/2c6c94a8311dbd832642b250003bbebd/explorando-el-sistema-con-python-3.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"metadata": {
"id": "WC-NQNacaF4K",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"# Explorando las características de un sistema usando Python 3\n",
"\n",
"URL | Gist\n",
"---: | : --- \n",
"https://goo.gl/FwEc1w | https://gist.github.com/hlecuanda/a403f94ab24b933f4bf2844d2b15e8c5\n",
"Héctor Lecuanda Ontiveros | hector (at) lecuanda.com · [Telegram][5] · [Twitter][2] · [Github][3] · [LinkedIn][4] \n",
"\n",
"A continuacion demostraremos algunas rutinas muy simples para determinar las características del sistema donde está siendo ejectuado el interpretador. \n",
"\n",
"Las ruitinas adaptadas a este Notebook están completamente expuestas al contexto del interpretador, si se desea hacer uso de las rutinas en un script ejecutable, será necesario encapsularlas en una definición de función. Ya encapsuladas, podemos hacer uso de la excelente librería [Python Fire][1] para crear una herramienta CLI con subcomandos al estilo git\n",
"\n",
"## Plataforma\n",
"\n",
"el modulo `platform` nos provee de una sencilla interfase al programa `uname` con la ventaja de regresar un valor tipo *named tuple* lo que hace trivial extraer datos individuales del tuple, si eso es lo único que nos interesa:\n",
"\n",
"\n",
"[1]:https://github.com/google/python-fire\n",
"[2]:https://twitter.com/hlecuanda\n",
"[3]:https://github.com/hlecuanda\n",
"[4]:https://www.linkedin.com/in/hlecuanda/\n",
"[5]:https://t.me/hlecuanda"
]
},
{
"metadata": {
"id": "1LdEgz8QOxRr",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"import platform\n",
"platform.uname()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "wM7MtFo0TBUa",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"platform.uname().system"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "mU9IkdbuTGoL",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"platform.uname().machine"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "GYn6qDuLdj1K",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"El módulo `platform` ofresce una variedad de métodos ó funciones para interrogar distintas características del sistema. aquí por ejemplo determinamos el tipo de distribución Linux que está instalada así como una lista de distribuciones soportadas por el módulo. Para cualquiera de las distribuciones en la lista, podremos obtener más detalles usando otras funcioones en el módulo. \n",
"\n",
"Aqui interrogamos la version y nombre de la distribución con `platform. linux_distribution()` y la arquitectura del Kernel, usando `platform.architecture()`"
]
},
{
"metadata": {
"id": "zjT63CthT4TL",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"platform.linux_distribution()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "5y5J4L_TULpk",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"platform.architecture()"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "1tsdVLXbT91J",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"platform._supported_dists"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "aa4gu5uZev5g",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"En la documentación del módulo pueden encontrar muchos mas detalles y características interrogables."
]
},
{
"metadata": {
"id": "1nEqk7cEUZe2",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"# Para ver la documentacion del modulo, elimina el comentario y ejecuta esta celda\n",
"# Dejamos la celda como comentario para que no interrumpa el flujo de ejecucion \n",
"# cuando se ejecutan todas las celdas secuencialmente, por ejemplo la primera\n",
"# vez que se ejecuta todo el notebook.\n",
"\n",
"\n",
"# platform??"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "eXWrbf3wU10p",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## CPU\n",
"\n",
"Las características del CPU de cualquier distribución Linux Moderna, cuenta con el sistema de archivos `proc`. podemos obtener informacion sobre los dispositivos del sistema simplemente listando los archivos en este sistema de archivos. \n",
"\n",
"En nuestro caso, usaremos con mucha frecuencia el recurso idiomático \n",
"\n",
" with open('path/to/file') as f:\n",
" for line in f:\n",
" print(line)\n",
"\n",
"Este modismo o recurso idiomático tiene la ventaja de cerrar automáticamente las referencias a cualquier archivo abierto que hayamos usado de manera limpia, asi como de asignar una variable con un generador al archivo que abrimos. \n",
"\n",
"Esto quiere decir que esa variable generará una secuencia con los conteindios del archivo sienmpre que sea interrogada por un iterador. En general, es mas sencillo de lo que \"suena\" \n",
"\n",
"Esta técnica se puede usar para leer directorios, o el contenido de archivos, incluso para leer el stream de datos que esta pasando por un dispositivo de red. después de todo, en el sistema de archivos `/proc` todo dispositivo se comporta y se puede manipular como un archivo cualquiera.-\n",
"\n",
"Aqui interrogamos los contenidos de `/proc/cpuinfo`\n"
]
},
{
"metadata": {
"id": "1ybU0emjU8v6",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"with open('/proc/cpuinfo') as f:\n",
" for line in f:\n",
" print(line.rstrip('\\n'))"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "8XylG24gVnjv",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Memoria\n",
"\n",
"Usaremos la misma técnica para determinar la memoria disponible del sistema, al leer el archivo `/proc/meminfo` Sólo agregaremos un poco de formato, para hacer mas amigable la salida del programa. Es escencialmente la misma secuencia que usamos para leer `/proc/cpuinfo`:"
]
},
{
"metadata": {
"id": "6WsTb0cEVsFJ",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"from collections import OrderedDict\n",
"\n",
"meminfo=OrderedDict()\n",
"\n",
"with open('/proc/meminfo') as f:\n",
" for line in f:\n",
" meminfo[line.split(':')[0]] = line.split(':')[1].strip()\n",
"\n",
"print('Total memory: {0}'.format(meminfo['MemTotal']))\n",
"print('Free memory: {0}'.format(meminfo['MemFree']))\n",
"\n",
"meminfo"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "Ywtrlv7gWxN_",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Estadisticas de red\n",
"\n",
"Los dispositivos de red, los podemos interrogar en ña rita `/proc/net/dev`\n",
"\n",
"De la misma manera que en el caso anterior, agregaremos un poco de formato para hacer de la salida de esta rutina un poco más amigable para consumo humano:"
]
},
{
"metadata": {
"id": "n2FzbDaGW6BZ",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"from collections import namedtuple\n",
"\n",
"with open('/proc/net/dev') as f:\n",
" net_dump = f.readlines()\n",
"\n",
"device_data={}\n",
"data = namedtuple('data',['rx','tx'])\n",
"for line in net_dump[2:]:\n",
" line = line.split(':')\n",
" if line[0].strip() != 'lo':\n",
" device_data[line[0].strip()] = data(float(line[1].split()[0])/(1024.0*1024.0), \n",
" float(line[1].split()[8])/(1024.0*1024.0))\n",
"\n",
"device_data"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "7o8tA-zEXvVA",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Procesos\n",
"Cada proceso que está siendo ejecutado se representa como un archivo en el directorio `/proc` Entonces, obtener una lista de los procesos en ejecución se reduce a listar el directorio proc. \n",
"\n",
" ls /proc\n",
" \n",
" Para hacer esto desde pythion sin recurrir al sistema operativo nos valdremos del módulo `os`. Esto es exactamente lo mismo que haríamos si quisieramos obtener un listado de todas las bitácoras en `/var/log` excepto que el directorio a interrogar es `/proc`:\n",
" \n",
" la técnica general es la siguiente:\n",
" \n",
" import os # importar modulo os\n",
" arreglo = [] # instanciar una lista para guardar nuestros resultados\n",
" for node in os.listdir('/path'): # iteramos en cada nodo del subdirectorio en /path\n",
" arreglo.append(node) # agregamos el nodo a nuestra lista. \n",
" \n",
" Para ser selectivos en cuanto a los nodos que se agregan a la lista solo hay que agregar condicionales para ejecturar el metodo append del arreglo, como es el caso en nuetro ejemplo:\n",
" \n",
" "
]
},
{
"metadata": {
"id": "hVCFp6lcXuQX",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"import os\n",
"pids = []\n",
"for subdir in os.listdir('/proc'):\n",
" if subdir.isdigit():\n",
" pids.append(subdir)\n",
"\n",
"pids"
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "hwZzd6edYJR6",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"## Dispositivos de bloque\n",
"\n",
"en este caso estamos combinando ambas técnicas, cada una en su propia subrutina. Los dispositivos de almacenamiento por bloques, se encuentran en la ruta `/sys/block/*` \n",
"\n",
"El siguiente listado, además hace uso del moduloo `glob` para interpretar la ruta con wildcard `/sys/blockk/*` generando el listados sólo de ese directorio- \n",
"\n",
"definimos tambien dos filtros, pues para este caso nos interesa solo listar los dispositivos tipo `sd.*` (stanrdard disk) y `mmcblk*`(tarjeta de memoria con almacenaje pro bloques, o bien tu tarjeta SD del teléfono) \n",
"\n",
"para encontrar los dispositivos de tipos específicos usaremos el módulo de expresiones retgulares `re` para generar un objeto de coinicidencia cuando el glob coincida con la expresión regular de tipo de dispositivo que estamos buscando. \n",
"\n",
"Finalmente agregamos formato para hacer de la salida una leyenda de fácil consumo para humanso:\n",
"\n",
"Hay que resaltar que la estructura básica para listar un directorio \n",
"\n",
" import os \n",
" arreglo = [] \n",
" for node in os.listdir('/path'): \n",
" arreglo.append(node) \n",
" \n",
"Y la estructura para leer un archivo:\n",
"\n",
" import os \n",
" arreglo = [] \n",
" for node in os.listdir('/path'): \n",
" arreglo.append(node) \n",
" \n",
"\n",
"Son las que están haciendo todo el trabajo. si acaso, se encuentran un poco escondidas entre estructuras adicionales como condicionalkes para agregar a la lista de archivos y formateo de la salida para consumo humano: "
]
},
{
"metadata": {
"id": "7jt3Nj2wYPu-",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"import glob\n",
"import re\n",
"import os\n",
"\n",
"# Add any other device pattern to read from\n",
"dev_pattern = ['sd.*','mmcblk*']\n",
"\n",
"def size(device):\n",
" nr_sectors = open(device+'/size').read().rstrip('\\n')\n",
" sect_size = open(device+'/queue/hw_sector_size').read().rstrip('\\n')\n",
"\n",
" # The sect_size is in bytes, so we convert it to GiB and then send it back\n",
" return (float(nr_sectors)*float(sect_size))/(1024.0*1024.0*1024.0)\n",
"\n",
"def detect_devs():\n",
" for device in glob.glob('/sys/block/*'):\n",
" for pattern in dev_pattern:\n",
" if re.compile(pattern).match(os.path.basename(device)):\n",
" print('Device:: {0}, Size:: {1} GiB'.format(device, size(device)))\n",
"\n",
"\n",
" "
],
"execution_count": 0,
"outputs": []
},
{
"metadata": {
"id": "mGBDfBehYeBq",
"colab_type": "text"
},
"cell_type": "markdown",
"source": [
"Ahora solo ejecutamos la funcion definida"
]
},
{
"metadata": {
"id": "JUyJQUBmYe7O",
"colab_type": "code",
"colab": {}
},
"cell_type": "code",
"source": [
"detect_devs()"
],
"execution_count": 0,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment