Звідки «немедленно» витягує інформацію?


24

Звідки uname -iбереться інформація?

Чи існують деталі /etc/?

Чи існують деталі /proc/?

Якщо так, на який файл він посилається, щоб вивести ці деталі?


Відповіді:


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}, {ім'я хоста}, {osrelease}, {версія} і {доменне ім'я}" проблема полягає в що жоден із цих файлів не посилається ні на що, вказуючи "x86_64". Будь-які інші рекомендації?
Рой Ернандес

@RoyHernandez Який результат locate --regex '^/usr/include/.*/sys/utsname.h$'?
heemayl

Вихід: "/usr/include/x86_64-linux-gnu/sys/utsname.h"
Рой Ернандес,

@RoyHernandez Це говорить про те, що файл існує, і ви щось робили неправильно ..
heemayl

Коли я запускаю uname -iвихід, є x86_64. Коли я запускаю locate --regex '^/usr/include/.*/sys/utsname.h$'результат, повертається/usr/include/x86_64-linux-gnu/sys/utsname.h
Рой Ернандес

22

Програма 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 -i", вихід "x86_64". Коли я перетинаю посилання "/usr/include/x86_64-linux-gnu/sys/utsname.h", я не бачу нічого, що посилається на "x86_64". Я посилався на "man 2 uname", і в ньому зазначається, що частина інформації utsname посилається через "/ proc / sys / kernel / {ostype}, {ім'я хоста}, {osrelease}, {версія} і {доменне ім'я}" проблема полягає в що жоден із цих файлів не посилається ні на що, вказуючи "x86_64". Будь-які інші рекомендації?
Рой Ернандес

@RoyHernandez In C можна визначити архітектуру процесора, виходячи з розміру, який приймає ціле число, наприклад - див. Тут . Тому uname.cне обов’язково використовувати для цього бібліотеку - ми, звичайно, можемо переконатися в вихідному коді.
Сергій Колодяжний

Насправді вона покладається на бібліотеку. . . machine.h
Сергій Колодяжний

machine.hначебто, всьому системі. На який machine.hфайл він покладається?
Рой Ернандес

@RoyHernandez все перераховане machine.hв моїй системі, здається, знаходиться в /usr/src/linux-headers-3.19.0-33каталозі. Цілком ймовірно, що він використовує бібліотеку, яку надає поточне ядро
Сергій Колодяжний,

6

Звичайно, відповідь Хемайла правильна.

Для задоволення, ось робочий фрагмент 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 Від структури utsname, яка заповнюється під час дзвінка до uname(). Приклад, ймовірно, не надто простий для тих, хто не має основ C, але ось, що трапляється більш-менш: a struct(тип даних C) типу utsnamename utsname(тип визначений у <sys/utsname.h>) оголошується; тоді вказівник на його ім’я utsname_ptrоголошується (оскільки uname()приймає вказівник на structтип типу utsnameяк аргумент, хоча цього можна було уникнути в цьому випадку, але це вже інша історія).
kos

Тоді виклик до uname()має ефект заповнення структури utsname, яка на момент printf()виклику містить різні значення всередині різних полів. На жаль, якщо ви не знайомі з C, це, ймовірно, не буде легко зрозуміти детально, але справа в тому, що uname()заповнюється структура даних, побудована за призначенням, поля якої згодом надрукуються через printf().
kos

4

Як додаток до відповіді heemayl, ви можете отримати деяку інформацію, як у unameкоманді, від /proc/version.


/ proc / версія містить "Linux версії 3.19.0-47-generic (buildd @ lgw01-19) (gcc версія 4.8.2 (Ubuntu 4.8.2-19ubuntu1)) # 53 ~ 14.04.1-Ubuntu SMP пн 18 січня 16 : 09: 14 UTC 2016 "та" unme -i "вихід" x86_64 ".
Рой Ернандес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.