Откуда uname -i
берется информация?
Существуют ли детали в /etc/
?
Существуют ли детали в /proc/
?
Если да, то на какой файл он ссылается для вывода этих деталей?
Откуда uname -i
берется информация?
Существуют ли детали в /etc/
?
Существуют ли детали в /proc/
?
Если да, то на какой файл он ссылается для вывода этих деталей?
Ответы:
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
чтобы получить больше представления об этом.
locate --regex '^/usr/include/.*/sys/utsname.h$'
?
uname -i
вывод x86_64
. Когда я запускаю locate --regex '^/usr/include/.*/sys/utsname.h$'
выходной возвращается/usr/include/x86_64-linux-gnu/sys/utsname.h
Программа strace
позволяет нам просматривать системные вызовы, которые может выполнять приложение. С uname -a
это очевидно , что только open
звонки идут в системные библиотеки, так что технически нет файла в файловой системе , что uname
открывает для чтения. Скорее это делает системные вызовы, используя библиотеки C.
Как правильно указал Heemayl, существует системный вызов для извлечения информации, хранящейся в uname
структуре. Это страница руководства, предлагает следующее:
Это системный вызов, и операционная система предположительно знает его имя, версию и версию. , , , , , Часть информации о имени пользователя также доступна через / proc / sys / ядро / {ostype, hostname, osrelease, version, domainname}.
Часть информации о имени пользователя также доступна через / proc / sys / ядро / {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.c
этого не обязательно использовать библиотеку - мы можем, конечно, взглянуть на исходный код.
machine.h
machine.h
кажется, пронизано всей системой. На какой machine.h
файл он опирается?
machine.h
в моей системе, похоже, находятся в /usr/src/linux-headers-3.19.0-33
каталоге. Весьма вероятно, что он использует библиотеку, предоставляемую в настоящее время работающим ядром
Конечно, ответ Химейла правильный.
Просто для удовольствия, вот рабочий фрагмент 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);
берется информация?
utsname
, которая заполняется во время вызова uname()
. Этот пример, вероятно, не слишком прост для тех, кто не знает основ C, но вот более или менее то, что происходит: объявлен struct
(тип данных C) типа utsname
named utsname
(тип, определенный в <sys/utsname.h>
); затем utsname_ptr
объявляется указатель на него с именем (так как в качестве аргумента uname()
принимает указатель на struct
тип utsname
, хотя этого можно было бы избежать в этом случае, но это уже другая история).
uname()
заполняет структуру utsname
, которая во время printf()
вызова содержит различные значения внутри различных полей. К сожалению, если вы не знакомы с C, это, вероятно, не будет легко понять подробно, но дело в том, что uname()
заполняет структуру данных, созданную специально, поля которой впоследствии распечатываются printf()
.
В дополнение к ответу Heemayl, вы можете получить некоторую информацию, как в uname
команде от /proc/version
.