uname
.El programa uname
está disponible en prácticamente todos los sistemas UNIX desde el siglo pasado. Según wikipedia, uname
fue introducido por primera vez en el sistema PWB/UNIX, allá por los 70.
uname
uname
nos proporciona información sobre el nombre, versión o arquitectura de la máquina sobre la que se ejecuta. No vamos a reproducir aquí la página del manual, así que los que queráis conocer todos los detalles... ya sabéis man uname
.
Lo que si vamos a mostrar es la información que nos proporciona cuando utilizamos el flag -a
. Este flag es común en muchas utilidades de línea de comandos y suele ser la versión reducida el flag largo --all
que viene a ser algo asi como: Dame todo lo que tengas babe.
En el caso de uname
y en este ordenado en el que estoy escribiendo este artículo, el resultado sería este:
Linux Razor 4.15.0-47-generic #50-Ubuntu SMP Wed Mar 13 10:44:52 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
O en otras palabras:
KERNEL-NAME NODENAME KERNEL-RELEASE KERNEL-VERSION
MACHINE PROCESSOR HARDWARE-PLATFORM OPERATING-SYSTEM
O en otras palabras más:
KERNEL-NAME : Linux
NODENAME : Razor
KERNEL-RELEASE : 4.15.0-47-generic
KERNEL-VERSION : #50-Ubuntu SMP Wed Mar 13 10:44:52 UTC 2019
MACHINE : x86_64
PROCESSOR : x86_64
HARDWARE-PLATFORM : x86_64
OPERATING-SYSTEM : GNU/Linux
A modo de ejemplo. Esto es lo que obtengo al ejecutar el comando en mi teléfono Android (en el que previamente he instalado busybox).
# uname -a
Linux localhost 3.4.0-gd59db4e #1 SMP PREEMPT Mon Mar 17 15:16:36 PDT 2014 armv7l GNU/Linux
En este caso, la versión que viene con Busybox no es capaz de proporcional ni el tipo procesador ni la arquitectura HW.
Como funciona el programa uname
?
Bien, ahora que ya sabemos que hace, vamos a ver como funciona. Como muchas de las herramientas primigenias de los sistemas UNIX, uname
no es más que un programa que da acceso al usuario a una llamada del sistema... Adivináis cual?... Si!. La llamada al sistema uname
.
Ahora podéis echarle un ojo con el comando man 2 uname
... Anda. Si todos esos parámetros que nos muestra la utilidad uname
aparecen ahí.
Venga, vamos a programar nuestro uname
mínimo. Sería algo como esto:
#include <stdio.h>
#include <sys/utsname.h>
int main (void) {
struct utsname un;
uname (&un);
printf ("%s %s %s %s %s\n",
un.sysname,
un.nodename,
un.release,
un.version,
un.machine);
}
Como decíamos, no es más que un wrapper alrededor de la llamada al sistema. Sin embargo, como podéis comprobar, los tres últimos valores no nos lo proporciona la llamada al sistema uname
. Así que nuestro uname
genera la misma salida que la versión que proporciona Busybox con una salvedad, el último parámetro.
Este último valor, el sistema operativo, se determina en tiempo de compilación... Para nuestro caso, podríamos simplemente añadirlo a la cadena de caracteres.
Los otros dos hay que conseguirlos por métodos alternativos.
Obteniendo información sobre el HW
La versión oficial de coreutils
de GNU no proporciona los valores de procesador y plataforma para los sistemas Linux. En nuestro ejemplo anterior, la versión de uname
proporcionada por Ubuntu está parcheada. Si descargamos las fuentes (apt source coreutils
no olvides de añadir los repositorios de fuentes), podremos echarle un ojo a lo que han hecho los chicos de Ubuntu.
Veamos primero como consiguen el valor del procesador:
struct utsname u;
uname(&u);
element = u.machine;
#ifdef linux
if(!strcmp(element, "i686")) { /* Check for Athlon */
char cinfo[1024];
FILE *f=fopen("/proc/cpuinfo", "r");
if(f) {
while(fgets(cinfo, 1024, f)) {
if(!strncmp(cinfo, "vendor_id", 9)) {
if(strstr(cinfo, "AuthenticAMD"))
element="athlon";
break;
}
}
fclose(f);
}
}
#endif
Como podéis ver no se complican mucho. En principio, asignan el valor de máquina (lo que es consecuente con nuestro resultado). En caso de que el valor de máquina retornado por uname
sea i686
, entonces utilizan /proc/cpuinfo
para determinar si se trata de un athlon
o no.
Con la plataforma hardware nos encontramos algo similar:
{
struct utsname u;
uname(&u);
element = u.machine;
if(strlen(element)==4 && element[0]=='i' && element[2]=='8' && element[3]=='6')
element[1]='3';
}
El programa simplemente comprueba si el valor machine
devuelto por uname
tiene la forma de i*86
. Si es el caso el segundo carácter se cambia a 3. De esta forma, si el valor de machine
será i386
para valores de este valor tales como i586
, i686
De donde sale esta información?
Bueno, quizás algunos os estaréis preguntando de donde sale esta información. Quizás imaginéis algún sofisticado sistema para determinar estos detalles, alguna oscura alquimia unixera oculta en lo más profundo del kernel... Pues siento desilusionaros, pero toda esta información está hard-codeada en el kernel.
Durante el proceso de configuración y compilación del kernel, toda esta información es compilada y almacena en el kernel. La llamada al sistema uname
simplemente nos devuelve esa información.
Más?
Seguiremos destripando las distintas herramientas de nuestro sistema y aprendiendo poco a poco todos sus secretos. No dudéis en hacernos saber en los comentarios que programa queréis que destripemos en el próximo artículo... y si no ya buscaremos nosotros algo :)
■