Da dove uname -iproviene l'informazione?
I dettagli esistono in /etc/?
I dettagli esistono in /proc/?
In tal caso, a quale file fa riferimento per generare tali dettagli?
Da dove uname -iproviene l'informazione?
I dettagli esistono in /etc/?
I dettagli esistono in /proc/?
In tal caso, a quale file fa riferimento per generare tali dettagli?
Risposte:
unameusa la chiamata di sistema uname(2)per ottenere le informazioni relative al kernel che mostra.
La sinossi è:
#include <sys/utsname.h>
int uname(struct utsname *buf);
dove uname(2)restituisce informazioni nella struttura indicata da buf. Inoltre è possibile leggere il file di intestazione utsname.hda /usr/include/"$(arch)"-linux-gnu/sys/utsname.hscavare più a fondo.
Dai un'occhiata man 2 unameper avere più idea a riguardo.
locate --regex '^/usr/include/.*/sys/utsname.h$'?
uname -ioutput è x86_64. Quando eseguo locate --regex '^/usr/include/.*/sys/utsname.h$'l'output ritorna/usr/include/x86_64-linux-gnu/sys/utsname.h
Il programma straceci consente di visualizzare le chiamate di sistema che un'applicazione può effettuare. Con uname -aè evidente che le sole openchiamate vanno a librerie di sistema, quindi tecnicamente non c'è alcun file sul filesystem che la unameapre per la lettura. Piuttosto effettua chiamate di sistema usando le librerie C.
Come ha correttamente sottolineato Heemayl, esiste una chiamata di sistema per recuperare le informazioni memorizzate nella unamestruttura. È la pagina man, suggerisce quanto segue:
Questa è una chiamata di sistema e il sistema operativo presumibilmente conosce il suo nome, versione e versione. . . . . . Parte delle informazioni sull'utsname sono accessibili anche tramite / proc / sys / ker-nel / {ostype, hostname, osrelease, versione, domainname}.
Parte delle informazioni sull'utsname sono accessibili anche tramite / proc / sys / ker-nel / {ostype, hostname, osrelease, versione, domainname}.
/procil filesystem tuttavia è virtuale, nel senso che esiste solo mentre il sistema operativo è in esecuzione. Pertanto, per alcuni aspetti, è impostato all'interno delle librerie del kernel o del sistema.
Infine, leggendo il codice sorgente di uname.ccui è possibile ottenere apt-get source coreutils, possiamo vedere che utilizza effettivamente la utsname.hlibreria (stampata con numeri di riga):
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 produzione:
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.cnon è necessario necessariamente utilizzare una libreria per questo - possiamo sicuramente vedere il codice sorgente, per essere sicuri.
machine.h
machine.hsembra essere disseminato in tutto il sistema. Su quale machine.hfile si basa?
machine.hsul mio sistema sembrano essere nella /usr/src/linux-headers-3.19.0-33directory. È molto probabile che usi la libreria fornita dal kernel attualmente in esecuzione
Naturalmente la risposta di Heemayl è corretta.
Solo per divertimento, ecco uno snippet C funzionante che mostra i dati restituiti da uname()(una specie di fatto in casa unamese vuoi): compilarlo con gcc uname.c -o unameed eseguirlo 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);proviene la sua informazione?
utsname, che viene popolata durante la chiamata a uname(). L'esempio probabilmente non è troppo semplice per chi non ha le basi di C, ma ecco cosa succede più o meno: viene dichiarato un struct(tipo di dati C) di tipo utsnamedenominato utsname(tipo definito in <sys/utsname.h>); quindi utsname_ptrviene dichiarato un puntatore al suo nome (poiché uname()accetta un puntatore a un structtipo utsnamecome argomento, anche se questo avrebbe potuto essere evitato in questo caso, ma questa è un'altra storia).
uname()ha l'effetto di popolare la struttura utsname, che al momento della printf()chiamata contiene i vari valori all'interno dei vari campi. Sfortunatamente, se non si ha familiarità con C, questo probabilmente non sarà facile da comprendere nei dettagli, ma il punto è che uname()popola una struttura di dati costruita appositamente, i cui campi vengono successivamente stampati tramite printf().
In aggiunta alla risposta di heemayl, puoi ottenere alcune informazioni come nel unamecomando da /proc/version.