Trường hợp không có thông tin rút ra từ đâu?


Câu trả lời:


31

unamesử dụng lệnh gọi hệ thống uname(2)để lấy thông tin liên quan đến kernel mà nó hiển thị.

Bản tóm tắt là:

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

nơi uname(2)trả về thông tin trong cấu trúc được chỉ bởi buf. Ngoài ra, bạn có thể đọc tệp tiêu đề utsname.htừ /usr/include/"$(arch)"-linux-gnu/sys/utsname.hđể đào sâu hơn.

Có một cái nhìn man 2 unameđể có thêm ý tưởng về điều này.


khi tôi chạy "uname -i", đầu ra là "x86_64". Khi tôi tham chiếu chéo "/usr/include/x86_64-linux-gnu/sys/utsname.h", tôi không thấy bất cứ điều gì tham chiếu "x86_64". Tôi đã tham chiếu "man 2 uname" và thông báo rằng một phần thông tin utsname được tham chiếu qua "/ Proc / sys / kernel / {lasype}, {hostname}, {osrelease}, {version} và {domainname}" không ai trong số các tệp đó tham chiếu bất cứ điều gì nêu rõ "x86_64". Bất kỳ khuyến nghị khác?
Roy Hernandez

@RoyHernandez Sản lượng của locate --regex '^/usr/include/.*/sys/utsname.h$'?
heemayl

Đầu ra là: "/usr/include/x86_64-linux-gnu/sys/utsname.h"
Roy Hernandez

@RoyHernandez Điều này cho biết rằng tập tin tồn tại và bạn đã làm gì đó sai ..
heemayl

Khi tôi chạy một uname -iđầu ra là x86_64. Khi tôi chạy locate --regex '^/usr/include/.*/sys/utsname.h$'kết quả đầu ra/usr/include/x86_64-linux-gnu/sys/utsname.h
Roy Hernandez

22

Chương trình stracecho phép chúng tôi xem các cuộc gọi hệ thống mà một ứng dụng có thể thực hiện. Với uname -anó rõ ràng rằng chỉ opencác cuộc gọi đi đến các thư viện hệ thống, vì vậy về mặt kỹ thuật không có tập tin trên hệ thống tập tin mà unamemở ra để đọc. Thay vào đó, nó thực hiện các cuộc gọi hệ thống bằng cách sử dụng các thư viện C.

Như heemayl đã chỉ ra một cách chính xác, có tồn tại lệnh gọi sys để lấy thông tin được lưu trữ trong unamecấu trúc. Đó là trang đàn ông, gợi ý như sau:

Đây là một cuộc gọi hệ thống và hệ điều hành có lẽ biết tên, phiên bản và phiên bản của nó. . . . . . Một phần thông tin utsname cũng có thể truy cập thông qua / Proc / sys / ker‐ nel / {lasype, tên máy chủ, osrelease, phiên bản, tên miền}.

Một phần thông tin utsname cũng có thể truy cập thông qua / Proc / sys / ker‐ nel / {lasype, tên máy chủ, osrelease, phiên bản, tên miền}.

/procTuy nhiên, hệ thống tập tin là ảo, có nghĩa là nó chỉ tồn tại trong khi HĐH đang chạy. Do đó, với một số phần mở rộng, nó được đặt trong các thư viện kernel hoặc hệ thống.

Cuối cùng, đọc qua mã nguồn uname.ccó thể lấy được apt-get source coreutils, chúng ta có thể thấy rằng nó thực sự sử dụng utsname.hthư viện (được in bằng số dòng):

 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 đầu ra:

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

khi tôi chạy "uname -i", đầu ra là "x86_64". Khi tôi tham chiếu chéo "/usr/include/x86_64-linux-gnu/sys/utsname.h", tôi không thấy bất cứ điều gì tham chiếu "x86_64". Tôi đã tham chiếu "man 2 uname" và thông báo rằng một phần thông tin utsname được tham chiếu thông qua "/ Proc / sys / kernel / {lasype}, {hostname}, {osrelease}, {version} và {domainname}" không ai trong số các tệp đó tham chiếu bất cứ điều gì nêu rõ "x86_64". Bất kỳ khuyến nghị khác?
Roy Hernandez

@RoyHernandez Trong C, có thể xác định kiến ​​trúc của CPU dựa trên kích thước mà số nguyên lấy, chẳng hạn - tham khảo tại đây . Vì vậy, uname.ckhông nhất thiết phải sử dụng một thư viện cho điều đó - tất nhiên chúng ta có thể nhìn vào mã nguồn để chắc chắn.
Sergiy Kolodyazhnyy

Trên thực tế, nó không dựa vào một thư viện. . . machine.h
Sergiy Kolodyazhnyy

machine.hdường như được tiêu trên toàn hệ thống. Những machine.htập tin nào nó dựa vào?
Roy Hernandez

@RoyHernandez tất cả các danh sách machine.htrên hệ thống của tôi dường như nằm trong /usr/src/linux-headers-3.19.0-33thư mục. Rất có khả năng nó sử dụng thư viện được cung cấp bởi kernel hiện đang chạy
Sergiy Kolodyazhnyy

6

Tất nhiên câu trả lời của heemayl là chính xác.

Để giải trí, đây là đoạn mã C hoạt động hiển thị dữ liệu được trả về uname()(một loại tự chế unamenếu bạn muốn): biên dịch nó với gcc uname.c -o unamevà chạy với ./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

mà là printf("%\n", utsname.machine);kéo nó thông tin từ đâu?
Roy Hernandez

@RoyHernandez Từ cấu trúc utsname, được điền trong cuộc gọi đến uname(). Ví dụ có lẽ không quá đơn giản với người không có kiến ​​thức cơ bản về C, nhưng đây là những gì xảy ra: một struct(kiểu dữ liệu C) utsnamecó tên utsname(kiểu được xác định trong <sys/utsname.h>) được khai báo; sau đó một con trỏ tới nó được đặt tên utsname_ptrđược khai báo (vì uname()chấp nhận một con trỏ đến một structkiểu utsnamelàm đối số, mặc dù điều này có thể tránh được trong trường hợp này, nhưng đó là một câu chuyện khác).
kos

Sau đó, lệnh gọi uname()có tác dụng điền vào cấu trúc utsname, tại thời điểm printf()cuộc gọi chứa các giá trị khác nhau bên trong các trường khác nhau. Thật không may nếu bạn không quen thuộc với C, điều này có lẽ sẽ không dễ nắm bắt chi tiết, nhưng điểm quan trọng là uname()tạo ra một cấu trúc dữ liệu được xây dựng trên mục đích, có các trường được in sau đó printf().
kos

4

Ngoài câu trả lời của heemayl, bạn có thể nhận được một số thông tin như trong unamelệnh từ /proc/version.


/ Proc / phiên bản chứa "Phiên bản Linux 3.19.0-47-generic (buildd @ lgw01-19) (phiên bản gcc 4.8.2 (Ubuntu 4.8.2-19ubfox1)) # 53 ~ 14.04.1-Ubuntu SMP Mon 18 tháng 1 : 09: 14 UTC 2016 "và đầu ra" uname -i "là" x86_64 ".
Roy Hernandez
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.