Звідки 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
структурі. Сторінка man, пропонує наступне:
Це системний виклик, і, ймовірно, операційна система знає свою назву, випуск та версію. . . . . . Частина інформації utsname також доступна через / proc / sys / kernel / {ostype, ім'я хоста, osrelease, версія, доменне ім’я}.
Частина інформації utsname також доступна через / proc / sys / kernel / {ostype, ім'я хоста, osrelease, версія, доменне ім’я}.
/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, але ось, що трапляється більш-менш: a struct
(тип даних C) типу utsname
name utsname
(тип визначений у <sys/utsname.h>
) оголошується; тоді вказівник на його ім’я utsname_ptr
оголошується (оскільки uname()
приймає вказівник на struct
тип типу utsname
як аргумент, хоча цього можна було уникнути в цьому випадку, але це вже інша історія).
uname()
має ефект заповнення структури utsname
, яка на момент printf()
виклику містить різні значення всередині різних полів. На жаль, якщо ви не знайомі з C, це, ймовірно, не буде легко зрозуміти детально, але справа в тому, що uname()
заповнюється структура даних, побудована за призначенням, поля якої згодом надрукуються через printf()
.
Як додаток до відповіді heemayl, ви можете отримати деяку інформацію, як у uname
команді, від /proc/version
.