D'où «uname» tire-t-il des informations?

24

D'où provient uname -il'information?

Les détails existent-ils en /etc/?

Les détails existent-ils en /proc/?

Si oui, à quel fichier fait-il référence pour produire ces détails?

Roy Hernandez
la source
EN RELATION
Mark Plotnick

Réponses:

31

unameutilise l'appel système uname(2)pour obtenir les informations relatives au noyau qu'il affiche.

Le synopsis est:

#include <sys/utsname.h>
int uname(struct utsname *buf);

uname(2)renvoie des informations dans la structure pointée par buf. Vous pouvez également lire le fichier d' en- tête utsname.hde /usr/include/"$(arch)"-linux-gnu/sys/utsname.hcreuser plus profond.

Jetez un oeil à man 2 unamepour avoir plus d'idée à ce sujet.

heemayl
la source
lorsque je lance "uname -i", la sortie est "x86_64". Lorsque je croise "/usr/include/x86_64-linux-gnu/sys/utsname.h", je ne vois rien qui fasse référence à "x86_64". J'ai référencé le "man 2 uname" et il indique qu'une partie des informations utsname est référencée via "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {version} et {domainname}" le problème est qu'aucun de ces fichiers ne fait référence à quoi que ce soit indiquant "x86_64". D'autres recommandations?
Roy Hernandez
@RoyHernandez Quelle est la sortie de locate --regex '^/usr/include/.*/sys/utsname.h$'?
heemayl
La sortie est: "/usr/include/x86_64-linux-gnu/sys/utsname.h"
Roy Hernandez
@RoyHernandez Cela indique que le fichier existe et que vous faisiez quelque chose de mal ..
heemayl
Lorsque je lance un, uname -ila sortie est x86_64. Quand j'exécute locate --regex '^/usr/include/.*/sys/utsname.h$'la sortie revient/usr/include/x86_64-linux-gnu/sys/utsname.h
Roy Hernandez
22

Le programme stracenous permet de visualiser les appels système qu'une application peut effectuer. Avec uname -ail est évident que les seuls openappels vont aux bibliothèques système, donc techniquement il n'y a pas de fichier sur le système de fichiers qui unames'ouvre pour la lecture. Il effectue plutôt des appels système à l'aide des bibliothèques C.

Comme heemayl l'a souligné à juste titre, il existe un appel sys pour récupérer les informations stockées dans la unamestructure. C'est la page de manuel, suggère ce qui suit:

Il s'agit d'un appel système, et le système d'exploitation connaît probablement son nom, sa version et sa version. . . . . . Une partie des informations utsname est également accessible via / proc / sys / ker‐ nel / {ostype, hostname, osrelease, version, domainname}.

Une partie des informations utsname est également accessible via / proc / sys / ker‐ nel / {ostype, hostname, osrelease, version, domainname}.

/procle système de fichiers est cependant virtuel, ce qui signifie qu'il n'existe que lorsque le système d'exploitation est en cours d'exécution. Ainsi, dans une certaine mesure, il est défini dans le noyau ou les bibliothèques système.

Enfin, en parcourant le code source uname.cdont on peut se procurer avec apt-get source coreutils, on constate qu'il utilise bien la utsname.hbibliothèque (imprimée avec des numéros de ligne):

 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 sortie:

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 +++
Sergiy Kolodyazhnyy
la source
lorsque je lance "uname -i", la sortie est "x86_64". Lorsque je croise "/usr/include/x86_64-linux-gnu/sys/utsname.h", je ne vois rien qui fasse référence à "x86_64". J'ai référencé le "man 2 uname" et il indique qu'une partie des informations utsname est référencée via "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {version} et {domainname}" le problème est qu'aucun de ces fichiers ne fait référence à quoi que ce soit indiquant "x86_64". D'autres recommandations?
Roy Hernandez
@RoyHernandez En C, il est possible de déterminer l'architecture d'un CPU en fonction de la taille que prend l'entier, par exemple - voir ici . Donc, il uname.cn'est pas nécessairement nécessaire d'utiliser une bibliothèque pour cela - nous pouvons bien sûr regarder le code source.
Sergiy Kolodyazhnyy
En fait, il repose sur une bibliothèque. . . machine.h
Sergiy Kolodyazhnyy
machine.hsemble être parsemé dans tout le système. machine.hSur quel fichier s'appuie-t-il?
Roy Hernandez
@RoyHernandez tous les listés machine.hsur mon système semblent être dans le /usr/src/linux-headers-3.19.0-33répertoire. Il est très probable qu'il utilise la bibliothèque fournie par le noyau en cours d'exécution
Sergiy Kolodyazhnyy
6

Bien sûr, la réponse de heemayl est correcte.

Juste pour le plaisir, voici un extrait de travail C présentant les données retournées par uname()(une sorte de maison unamesi vous le souhaitez): compilez-le gcc uname.c -o unameet exécutez-le avec ./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
kos
la source
d'où provient l' printf("%\n", utsname.machine);extraction de ses informations?
Roy Hernandez
@RoyHernandez Depuis la structure utsname, qui est remplie lors de l'appel à uname(). L'exemple n'est probablement pas trop simple pour quelqu'un qui n'a pas les bases de C, mais voici plus ou moins ce qui se passe: un struct(type de données C) de type utsnamenommé utsname(type défini dans <sys/utsname.h>) est déclaré; puis un pointeur sur celui-ci nommé utsname_ptrest déclaré (puisqu'il uname()accepte un pointeur sur un structtype utsnamecomme argument, bien que cela aurait pu être évité dans ce cas, mais c'est une autre histoire).
kos
Ensuite, l'appel à uname()a pour effet de remplir la structure utsnamequi, au moment de l' printf()appel, contient les différentes valeurs à l'intérieur des différents champs. Malheureusement, si vous n'êtes pas familier avec C, cela ne sera probablement pas facile à saisir en détail, mais le fait est qu'il uname()remplit une structure de données construite à dessein, dont les champs sont ensuite imprimés via printf().
kos
4

En complément de la réponse de heemayl, vous pouvez obtenir des informations comme dans la unamecommande de /proc/version.

Eduardo Cola
la source
/ proc / version contient "Linux version 3.19.0-47-generic (buildd @ lgw01-19) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)) # 53 ~ 14.04.1-Ubuntu SMP lun. 18 janv. 16 16 : 09: 14 UTC 2016 "et la sortie" uname -i "est" x86_64 ".
Roy Hernandez