¿De dónde uname -i
saca la información?
¿Existen los detalles en /etc/
?
¿Existen los detalles en /proc/
?
Si es así, ¿a qué archivo hace referencia para generar esos detalles?
¿De dónde uname -i
saca la información?
¿Existen los detalles en /etc/
?
¿Existen los detalles en /proc/
?
Si es así, ¿a qué archivo hace referencia para generar esos detalles?
Respuestas:
uname
usa la llamada uname(2)
al sistema para obtener la información relacionada con el núcleo que muestra.
La sinopsis es:
#include <sys/utsname.h>
int uname(struct utsname *buf);
donde uname(2)
devuelve información en la estructura señalada por buf
. También se puede leer el archivo de cabecera utsname.h
de /usr/include/"$(arch)"-linux-gnu/sys/utsname.h
cavar más profundo.
Echa un vistazo man 2 uname
para tener más idea sobre esto.
locate --regex '^/usr/include/.*/sys/utsname.h$'
?
uname -i
la salida es x86_64
. Cuando ejecuto locate --regex '^/usr/include/.*/sys/utsname.h$'
la salida vuelve/usr/include/x86_64-linux-gnu/sys/utsname.h
El programa strace
nos permite ver las llamadas al sistema que puede hacer una aplicación. Con uname -a
que es evidente que las únicas open
llamadas van a las bibliotecas del sistema, por lo que técnicamente no hay ningún archivo en el sistema de archivos que la uname
abre para la lectura. Más bien realiza llamadas al sistema utilizando las bibliotecas C.
Como heemayl señaló correctamente, existe una llamada sys para recuperar la información almacenada en la uname
estructura. Es la página de manual, sugiere lo siguiente:
Esta es una llamada al sistema, y el sistema operativo supuestamente conoce su nombre, versión y versión. . . . . . También se puede acceder a parte de la información de utsname a través de / proc / sys / kernel / {ostype, hostname, osrelease, version, domainname}.
También se puede acceder a parte de la información de utsname a través de / proc / sys / kernel / {ostype, hostname, osrelease, version, domainname}.
/proc
sin embargo, el sistema de archivos es virtual, lo que significa que existe solo mientras el sistema operativo se está ejecutando. Por lo tanto, hasta cierto punto, se establece dentro del núcleo o las bibliotecas del sistema.
Finalmente, leyendo el código fuente del uname.c
cual se puede obtener apt-get source coreutils
, podemos ver que de hecho usa la utsname.h
biblioteca (impresa con números de línea):
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <sys/utsname.h>
24 #include <getopt.h>
25
strace
salida:
skolodya@ubuntu:$ strace uname -a
execve("/bin/uname", ["uname", "-a"], [/* 58 vars */]) = 0
brk(0) = 0x1478000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efee6935000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=137226, ...}) = 0
mmap(NULL, 137226, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7efee6913000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\37\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1840928, ...}) = 0
mmap(NULL, 3949248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7efee6350000
mprotect(0x7efee650b000, 2093056, PROT_NONE) = 0
mmap(0x7efee670a000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ba000) = 0x7efee670a000
mmap(0x7efee6710000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7efee6710000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efee6912000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efee6910000
arch_prctl(ARCH_SET_FS, 0x7efee6910740) = 0
mprotect(0x7efee670a000, 16384, PROT_READ) = 0
mprotect(0x606000, 4096, PROT_READ) = 0
mprotect(0x7efee6937000, 4096, PROT_READ) = 0
munmap(0x7efee6913000, 137226) = 0
brk(0) = 0x1478000
brk(0x1499000) = 0x1499000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=7216688, ...}) = 0
mmap(NULL, 7216688, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7efee5c6e000
close(3) = 0
uname({sys="Linux", node="eagle", ...}) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efee6934000
uname({sys="Linux", node="eagle", ...}) = 0
uname({sys="Linux", node="eagle", ...}) = 0
write(1, "Linux eagle 4.1.0-040100rc2-gene"..., 113Linux eagle 4.1.0-040100rc2-generic #201505032335 SMP Mon May 4 03:36:35 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
) = 113
close(1) = 0
munmap(0x7efee6934000, 4096) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
uname.c
, no necesariamente necesita usar una biblioteca para eso; podemos mirar el código fuente, por supuesto, para estar seguros.
machine.h
machine.h
parece estar salpicada en todo el sistema. ¿En qué machine.h
archivo se basa?
machine.h
en mi sistema parecen estar en el /usr/src/linux-headers-3.19.0-33
directorio. Es muy probable que use la biblioteca proporcionada por el núcleo actualmente en ejecución
Por supuesto, la respuesta de heemayl es correcta.
Solo por diversión, aquí hay un fragmento de C en funcionamiento que muestra los datos devueltos por uname()
(una especie de casero uname
si lo desea): compílelo gcc uname.c -o uname
y ejecútelo con ./uname
:
#include <stdio.h> // printf()
#include <sys/utsname.h> // uname()
int main() {
int ret; // stores the return value of uname()
struct utsname utsname; // stores the data returned by uname()
struct utsname *utsname_ptr = &utsname; // pointer to the struct holding the data returned by uname()
ret = uname(utsname_ptr); // calls uname() on utsname_ptr and stores its return value in ret
/* prints the fields of utsname */
printf("%s\n", utsname.sysname);
printf("%s\n", utsname.nodename);
printf("%s\n", utsname.release);
printf("%s\n", utsname.version);
printf("%s\n", utsname.machine);
/* returns the return value of uname() */
return(ret);
}
% ./uname
Linux
user-X550CL
4.2.0-25-generic
#30-Ubuntu SMP Mon Jan 18 12:31:50 UTC 2016
x86_64
printf("%\n", utsname.machine);
saca la información?
utsname
, que se rellena durante la llamada a uname()
. El ejemplo probablemente no sea demasiado sencillo para alguien sin los conceptos básicos de C, pero aquí está más o menos lo que sucede: se declara un struct
(tipo de datos C) de tipo utsname
llamado utsname
(tipo definido en <sys/utsname.h>
); luego utsname_ptr
se declara un puntero al nombre (ya que uname()
acepta un puntero a un struct
tipo utsname
como argumento, aunque esto podría haberse evitado en este caso, pero esa es otra historia).
uname()
tiene el efecto de llenar la estructura utsname
, que en el momento de la printf()
llamada contiene los diversos valores dentro de los diversos campos. Desafortunadamente, si no está familiarizado con C, esto probablemente no será fácil de comprender en detalle, pero el punto es que uname()
puebla una estructura de datos construida a propósito, cuyos campos se imprimen más tarde printf()
.
Como una adición a la respuesta de heemayl, puede obtener información como en el uname
comando /proc/version
.