Woher bezieht "uname" Informationen?

24

Woher uname -ibezieht man die Informationen?

Existieren die Details in /etc/?

Existieren die Details in /proc/?

Wenn ja, auf welche Datei wird verwiesen, um diese Details auszugeben?

Roy Hernandez
quelle

Antworten:

31

unameVerwendet den Systemaufruf uname(2), um die angezeigten kernelbezogenen Informationen abzurufen.

Die Zusammenfassung ist:

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

Dabei werden uname(2)Informationen in der Struktur zurückgegeben, auf die von verwiesen wird buf. Sie können auch die Header-Datei utsname.hvon lesen /usr/include/"$(arch)"-linux-gnu/sys/utsname.h, um tiefer zu graben.

Schauen Sie sich das an man 2 uname, um mehr darüber zu erfahren.

heemayl
quelle
Wenn ich "uname -i" ausführe, lautet die Ausgabe "x86_64". Wenn ich auf "/usr/include/x86_64-linux-gnu/sys/utsname.h" verweise, wird nichts angezeigt, das auf "x86_64" verweist. Ich habe auf "man 2 uname" verwiesen und es heißt, dass ein Teil der utsname-Informationen über "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {version} und {domainname}" referenziert wird dass keine dieser Dateien auf etwas verweist, das "x86_64" angibt. Irgendwelche anderen Empfehlungen?
Roy Hernandez
@ RoyHernandez Was ist die Ausgabe von locate --regex '^/usr/include/.*/sys/utsname.h$'?
Heemayl
Die Ausgabe ist: "/usr/include/x86_64-linux-gnu/sys/utsname.h"
Roy Hernandez
@ RoyHernandez Dies sagt, dass die Datei existiert und Sie etwas falsch gemacht haben ..
Heemayl
Wenn ich ein laufe ist uname -idie Ausgabe x86_64. Wenn ich laufen locate --regex '^/usr/include/.*/sys/utsname.h$'die Ausgangs kehrt/usr/include/x86_64-linux-gnu/sys/utsname.h
Roy Hernandez
22

Das Programm straceermöglicht es uns, die Systemaufrufe einer Anwendung anzuzeigen. Mit uname -aoffensichtlich ist , dass nur die openAnrufe über Systembibliotheken, so technisch keine Datei dort auf dem Dateisystem ist , dass die unamezum Lesen geöffnet. Vielmehr werden Systemaufrufe unter Verwendung der C-Bibliotheken durchgeführt.

Wie er richtig ausgeführt hat, gibt es einen Systemaufruf zum Abrufen der in der unameStruktur gespeicherten Informationen . Die Manpage schlägt Folgendes vor:

Dies ist ein Systemaufruf, und das Betriebssystem kennt vermutlich seinen Namen, seine Version und seine Version. . . . . . Ein Teil der utsname-Informationen ist auch über / proc / sys / kernel / {ostype, hostname, osrelease, version, domainname} zugänglich.

Ein Teil der utsname-Informationen ist auch über / proc / sys / kernel / {ostype, hostname, osrelease, version, domainname} zugänglich.

/procDas Dateisystem ist jedoch virtuell, was bedeutet, dass es nur existiert, während das Betriebssystem ausgeführt wird. In gewissem Umfang ist es also in Kernel- oder Systembibliotheken festgelegt.

Schließlich uname.ckönnen apt-get source coreutilswir beim Durchlesen des Quellcodes, mit dem er abgerufen werden kann , feststellen, dass die utsname.hBibliothek tatsächlich verwendet wird (gedruckt mit Zeilennummern):

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

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
quelle
Wenn ich "uname -i" ausführe, lautet die Ausgabe "x86_64". Wenn ich auf "/usr/include/x86_64-linux-gnu/sys/utsname.h" verweise, wird nichts angezeigt, das auf "x86_64" verweist. Ich habe auf "man 2 uname" verwiesen und es heißt, dass ein Teil der utsname-Informationen über "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {version} und {domainname}" referenziert wird dass keine dieser Dateien auf etwas verweist, das "x86_64" angibt. Irgendwelche anderen Empfehlungen?
Roy Hernandez
@RoyHernandez In C ist es möglich, die Architektur einer CPU basierend auf der Größe zu bestimmen, die beispielsweise eine Ganzzahl annimmt - siehe hier . Sie müssen dafür uname.calso nicht unbedingt eine Bibliothek verwenden - wir können uns natürlich den Quellcode ansehen, um sicherzugehen.
Sergiy Kolodyazhnyy
Eigentlich ist es auf eine Bibliothek angewiesen. . .machine.h
Sergiy Kolodyazhnyy
machine.hscheint im ganzen System gespickt zu sein. Welchemachine.h Datei stützt es sich?
Roy Hernandez
@ RoyHernandez alle machine.hauf meinem System aufgeführten scheinen in dem /usr/src/linux-headers-3.19.0-33Verzeichnis zu sein. Es ist sehr wahrscheinlich, dass die vom aktuell ausgeführten Kernel bereitgestellte Bibliothek verwendet wird
Sergiy Kolodyazhnyy,
6

Natürlich ist Heemayls Antwort richtig.

Aus Spaß ist hier ein funktionierender C-Ausschnitt, der die von zurückgegebenen Daten zeigt uname() (eine Art hausgemachtes, unamewenn Sie möchten): Kompilieren Sie es mit gcc uname.c -o unameund führen Sie es aus mit ./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
quelle
Woher kommt die printf("%\n", utsname.machine);Information?
Roy Hernandez
@RoyHernandez Aus der Struktur utsname, die beim Aufruf von aufgefüllt wird uname(). Das Beispiel ist für jemanden ohne C-Grundkenntnisse wahrscheinlich nicht so einfach, aber hier ist mehr oder weniger, was passiert: Ein struct(C-Datentyp) vom Typ utsnamenamed utsname(Typ definiert in <sys/utsname.h>) wird deklariert; dann wird ein Zeiger auf den Namen utsname_ptrdeklariert (da uname()ein Zeiger auf einen structTyp utsnameals Argument akzeptiert wird , obwohl dies in diesem Fall hätte vermieden werden können, aber das ist eine andere Geschichte).
Kos
Der Aufruf von uname()bewirkt dann, dass die Struktur aufgefüllt wird utsname, die zum Zeitpunkt des printf()Aufrufs die verschiedenen Werte in den verschiedenen Feldern enthält. Wenn Sie mit C nicht vertraut sind, ist dies wahrscheinlich nicht leicht im Detail zu erfassen, aber der Punkt ist, dass uname()eine absichtlich aufgebaute Datenstruktur aufgefüllt wird , über deren Felder später gedruckt wird printf().
Kos
4

Als Ergänzung zu Heemayls Antwort erhalten Sie Informationen wie in der uname Befehl von /proc/version.

Eduardo Cola
quelle
/ proc / version enthält "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 Mon Jan 18 16 : 09: 14 UTC 2016 "und" uname -i "werden als" x86_64 "ausgegeben.
Roy Hernandez