“ uname”从哪里获取信息?


Answers:


31

uname使用系统调用uname(2)获取它显示的与内核相关的信息。

概要是:

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

其中以uname(2)返回的结构返回信息buf。你也可以读取头文件utsname.h/usr/include/"$(arch)"-linux-gnu/sys/utsname.h越挖越深。

看看man 2 uname以获得更多关于此的想法。


当我运行“ uname -i”时,输出为“ x86_64”。当我交叉引用“ /usr/include/x86_64-linux-gnu/sys/utsname.h”时,看不到任何引用“ x86_64”的内容。我引用了“ man 2 uname”,它指出部分utsname信息是通过“ / proc / sys / kernel / {ostype},{hostname},{osrelease},{version}和{domainname}”引用的,问题是这些文件都没有引用任何说明“ x86_64”的内容。还有其他建议吗?
罗伊·埃尔南德斯

@RoyHernandez的输出是locate --regex '^/usr/include/.*/sys/utsname.h$'什么?
heemayl

输出为:“ / usr / include / x86_64
Roy Hernandez

@RoyHernandez这表明文件确实存在,并且您做错了..
heemayl 2016年

当我运行一个uname -i输出是x86_64。当我运行locate --regex '^/usr/include/.*/sys/utsname.h$'输出返回时/usr/include/x86_64-linux-gnu/sys/utsname.h
Roy Hernandez

22

该程序strace使我们可以查看应用程序可能进行的系统调用。随着uname -a它的明显的,唯一的open电话将转到系统库,因此在技术上存在于文件系统没有文件的uname打开阅读。而是使用C库进行系统调用。

正如heemayl正确指出的那样,存在sys调用来检索存储在uname结构中的信息。这是手册页,建议以下内容:

这是一个系统调用,操作系统大概知道其名称,发行版和版本。。。。。。utsname信息的一部分也可以通过/ proc / sys / kernel / {ostype,hostname,osrelease,version,domainname}访问。

utsname信息的一部分也可以通过/ proc / sys / kernel / {ostype,hostname,osrelease,version,domainname}访问。

/proc但是,文件系统是虚拟的,这意味着它仅在操作系统运行时才存在。因此,在某种程度上,它是在内核或系统库中设置的。

最后,通读uname.c可以通过获得的源代码apt-get source coreutils,我们可以看到它确实使用了utsname.h库(印有行号):

 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 输出:

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 -i”时,输出为“ x86_64”。当我交叉引用“ /usr/include/x86_64-linux-gnu/sys/utsname.h”时,看不到任何引用“ x86_64”的东西。我引用了“ man 2 uname”,它指出部分utsname信息是通过“ / proc / sys / kernel / {ostype},{hostname},{osrelease},{version}和{domainname}”引用的,问题是这些文件都没有引用任何说明“ x86_64”的内容。还有其他建议吗?
罗伊·埃尔南德斯

@RoyHernandez在C语言中,可以根据整数所占用的大小来确定CPU的体系结构,例如,请参阅此处。因此,uname.c不一定需要为此使用库-当然,我们可以查看源代码。
Sergiy Kolodyazhnyy

实际上,它确实依赖于库。。。machine.h
Sergiy Kolodyazhnyy

machine.h似乎遍布整个系统。machine.h它依赖哪个文件?
罗伊·埃尔南德斯

@RoyHernandez machine.h我的系统上列出的所有内容似乎都在该/usr/src/linux-headers-3.19.0-33目录中。它很有可能使用当前正在运行的内核提供的库
Sergiy Kolodyazhnyy,2016年

6

当然,heemayl的答案是正确的。

只是为了好玩,这是一个工作的C代码片段,其中显示了返回的数据uname()uname如果需要的话,gcc uname.c -o uname它是一种自制的):使用进行编译并使用进行运行./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);从拉动的信息?
罗伊·埃尔南德斯

@RoyHernandez来自struct utsname,该结构是在调用期间填充的uname()。对于没有C基础知识的人来说,该示例可能不太简单,但是,这里发生的事情或多或少:声明了一个名为(在中定义的struct类型)的(C数据类型);然后声明一个指向它的指针(因为接受类型的指针作为参数,尽管在这种情况下可以避免这种情况,但这是另一回事了)。utsnameutsname<sys/utsname.h>utsname_ptruname()structutsname
kos

然后,对的调用uname()具有填充struct的效果,该结构utsnameprintf()调用时包含各个字段内的各个值。不幸的是,如果您不熟悉C,可能不会很容易详细地理解它,但是重点是uname()填充了一个有意构建的数据结构,其字段随后通过进行打印printf()
kos

4

除了heemayl的答案之外,您还可以从中获得一些信息,如uname命令所示/proc/version


/ proc / version包含“ Linux版本3.19.0-47-generic(buildd @ lgw01-19)(gcc版本4.8.2(Ubuntu 4.8.2-19ubuntu1))#53〜14.04.1-Ubuntu SMP 1月18日星期一:09:14 UTC 2016“和” uname -i“输出为” x86_64“。
罗伊·埃尔南德斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.