Dari mana "tidak dikenal" menarik informasi?


Jawaban:


31

unamemenggunakan panggilan sistem uname(2)untuk mendapatkan informasi terkait kernel yang ditampilkan.

Sinopsisnya adalah:

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

di mana uname(2)mengembalikan informasi dalam struktur yang ditunjukkan oleh buf. Anda juga dapat membaca file header utsname.hdari /usr/include/"$(arch)"-linux-gnu/sys/utsname.huntuk menggali lebih dalam.

Lihatlah man 2 unameuntuk mendapatkan lebih banyak ide tentang ini.


ketika saya menjalankan "uname -i", hasilnya adalah "x86_64". Ketika saya melewati referensi "/ usr/include/x86_64-linux-gnu/sys/utsname.h", saya tidak melihat apa pun yang merujuk "x86_64". Saya mereferensikan "man 2 uname" dan menyatakan bahwa sebagian informasi utsname dirujuk melalui "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {versi} dan {domainname}" masalahnya adalah bahwa tidak satu pun dari file-file itu referensi apa pun yang menyatakan "x86_64". Ada rekomendasi lain?
Roy Hernandez

@ RoyHernandez Apa hasil dari locate --regex '^/usr/include/.*/sys/utsname.h$'?
heemayl

Outputnya adalah: "/usr/include/x86_64-linux-gnu/sys/utsname.h"
Roy Hernandez

@RoyHernandez Ini memberi tahu bahwa file tersebut memang ada dan Anda melakukan sesuatu yang salah ..
heemayl

Ketika saya menjalankan uname -ioutput x86_64. Ketika saya menjalankan locate --regex '^/usr/include/.*/sys/utsname.h$'pengembalian output/usr/include/x86_64-linux-gnu/sys/utsname.h
Roy Hernandez

22

Program ini stracememungkinkan kita untuk melihat panggilan sistem yang mungkin dibuat oleh aplikasi. Dengan uname -ajelas bahwa satu-satunya openpanggilan masuk ke pustaka sistem, jadi secara teknis tidak ada file pada sistem file yang unameterbuka untuk dibaca. Alih-alih itu membuat panggilan sistem menggunakan perpustakaan C.

Seperti yang ditunjukkan oleh heemayl dengan benar, ada panggilan sistem untuk mengambil informasi yang disimpan dalam unamestruktur. Ini halaman manual, menyarankan yang berikut:

Ini adalah panggilan sistem, dan sistem operasi mungkin tahu nama, rilis, dan versinya. . . . . . Bagian dari informasi utsname juga dapat diakses melalui / proc / sys / ker-nel / {ostype, hostname, osrelease, versi, domainname}.

Bagian dari informasi utsname juga dapat diakses melalui / proc / sys / ker-nel / {ostype, hostname, osrelease, versi, domainname}.

/procfilesystem adalah virtual, artinya hanya ada saat OS berjalan. Jadi untuk beberapa perluasan diatur dalam kernel atau sistem perpustakaan.

Akhirnya, membaca kode sumber uname.cyang dapat diperoleh dengan apt-get source coreutils, kita dapat melihat bahwa itu memang menggunakan utsname.hperpustakaan (dicetak dengan nomor baris):

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

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 +++

ketika saya menjalankan "uname -i", outputnya adalah "x86_64". Ketika saya melewati referensi "/ usr/include/x86_64-linux-gnu/sys/utsname.h", saya tidak melihat apa pun yang merujuk "x86_64". Saya mereferensikan "man 2 uname" dan menyatakan bahwa sebagian informasi utsname dirujuk melalui "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {versi} dan {domainname}" masalahnya adalah bahwa tidak satu pun dari file-file itu referensi apa pun yang menyatakan "x86_64". Ada rekomendasi lain?
Roy Hernandez

@ RoyHernandez Dalam C dimungkinkan untuk menentukan arsitektur CPU berdasarkan ukuran yang diambil integer, misalnya - lihat di sini . Jadi uname.ctidak perlu menggunakan perpustakaan untuk itu - kita bisa melihat kode sumber, tentu saja, untuk memastikan.
Sergiy Kolodyazhnyy

Sebenarnya, itu bergantung pada perpustakaan. . . machine.h
Sergiy Kolodyazhnyy

machine.htampaknya dibumbui di seluruh sistem. machine.hFile mana yang diandalkannya?
Roy Hernandez

@RoyHernandez semua yang terdaftar machine.hdi sistem saya tampaknya berada di /usr/src/linux-headers-3.19.0-33direktori. Sangat mungkin bahwa ia menggunakan perpustakaan yang disediakan oleh kernel yang sedang berjalan
Sergiy Kolodyazhnyy

6

Tentu saja jawaban heemayl benar.

Hanya untuk bersenang-senang, ini cuplikan C yang berfungsi untuk menampilkan data yang dikembalikan oleh uname()(semacam buatan rumah unamejika Anda mau): kompilasi dengan gcc uname.c -o unamedan jalankan dengan ./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

dari mana printf("%\n", utsname.machine);menarik informasi itu?
Roy Hernandez

@RoyHernandez Dari struct utsname, yang diisi selama panggilan ke uname(). Contohnya mungkin itu tidak terlalu mudah untuk seseorang tanpa dasar-dasar C, tapi inilah yang kira-kira terjadi: a struct(tipe data C) dari jenis yang utsnamedinamai utsname(tipe didefinisikan dalam <sys/utsname.h>) dideklarasikan; kemudian sebuah pointer ke namanya disebutkan utsname_ptr(karena uname()menerima pointer ke structtipe utsnamesebagai argumen, meskipun ini bisa dihindari dalam kasus ini, tapi itu cerita lain).
kos

Kemudian panggilan untuk uname()memiliki efek mengisi struct utsname, yang pada saat printf()panggilan berisi berbagai nilai di dalam berbagai bidang. Sayangnya jika Anda tidak terbiasa dengan C, ini mungkin tidak akan mudah untuk dipahami secara detail, tetapi intinya adalah bahwa uname()mengisi struktur data yang dibangun dengan sengaja, yang bidangnya nanti dicetak melalui printf().
kos

4

Sebagai tambahan untuk jawaban heemayl, Anda dapat memperoleh beberapa informasi seperti pada unameperintah dari /proc/version.


/ proc / version berisi "Linux versi 3.19.0-47-generik (buildd @ lgw01-19) (versi gcc 4.8.2 (Ubuntu 4.8.2-19ubuntu1)) # 53 ~ 14.04.1-Ubuntu SMP Mon 18 Jan : 09: 14 UTC 2016 "dan" uname -i "output adalah" x86_64 ".
Roy Hernandez
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.