"uname" ดึงข้อมูลจากที่ไหน


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}, {hostname}, {osrelease}, {version} และ {domainname}" ปัญหาคือ ไม่มีไฟล์ใดที่อ้างอิงถึงสิ่งที่ระบุว่า "x86_64" มีคำแนะนำอื่น ๆ อีกไหม?
Roy Hernandez

@ RoyHernandez เอาท์พุทของlocate --regex '^/usr/include/.*/sys/utsname.h$'อะไร?
heemayl

ผลลัพธ์คือ: "/usr/include/x86_64-linux-gnu/sys/utsname.h"
Roy Hernandez

@RoyHernandez นี้จะบอกว่าไฟล์ไม่อยู่และคุณกำลังทำอะไรผิดพลาด ..
heemayl

เมื่อผมทำงานออกเป็นuname -i x86_64เมื่อฉันรันlocate --regex '^/usr/include/.*/sys/utsname.h$'เอาต์พุตที่ส่งคืน/usr/include/x86_64-linux-gnu/sys/utsname.h
Roy Hernandez

22

โปรแกรมstraceช่วยให้เราสามารถดูระบบที่เรียกว่าแอพพลิเคชั่น ด้วยuname -aก็เห็นได้ชัดว่าเพียงopenโทรไปที่ระบบห้องสมุดดังนั้นในทางเทคนิคไม่มีแฟ้มในระบบแฟ้มที่unameเปิดสำหรับการอ่าน ค่อนข้างจะทำการโทรของระบบโดยใช้ไลบรารี C

เนื่องจาก heemayl ชี้ให้เห็นอย่างถูกต้องมีการเรียก sys เพื่อดึงข้อมูลที่เก็บไว้ในunameโครงสร้าง เป็นหน้าคนแนะนำต่อไปนี้:

นี่คือการเรียกของระบบและระบบปฏิบัติการน่าจะรู้ชื่อรุ่นและรุ่นของมัน . . . . . ส่วนของข้อมูล utsname นั้นยังสามารถเข้าถึงได้ผ่าน / proc / sys / ker‐ nel / {ostype, hostname, osrelease, version, domainname}

ส่วนของข้อมูล utsname นั้นยังสามารถเข้าถึงได้ผ่าน / proc / sys / ker‐ nel / {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 -i" ผลลัพธ์คือ "x86_64" เมื่อฉันอ้างอิงข้าม "/usr/include/x86_64-linux-gnu/sys/utsname.h" ฉันไม่เห็นสิ่งที่อ้างอิง "x86_64" ฉันอ้างอิง "man 2 uname" และระบุว่าส่วนของข้อมูล utsname ถูกอ้างอิงผ่าน "/ proc / sys / kernel / {ostype}, {hostname}, {osrelease}, {version} และ {domainname}" ปัญหาคือ ไม่มีไฟล์ใดที่อ้างอิงถึงสิ่งที่ระบุว่า "x86_64" มีคำแนะนำอื่น ๆ อีกไหม?
Roy Hernandez

@RoyHernandez ใน C มันเป็นไปได้ในการกำหนดสถาปัตยกรรมของซีพียูขึ้นอยู่กับขนาดที่จำนวนเต็มใช้เวลาเช่น - ดูที่นี่ ดังนั้นuname.cไม่จำเป็นต้องใช้ไลบรารีสำหรับสิ่งนั้น - เราสามารถดูซอร์สโค้ดแน่นอนเพื่อให้แน่ใจ
Sergiy Kolodyazhnyy

จริงๆแล้วมันขึ้นอยู่กับห้องสมุด . . machine.h
Sergiy Kolodyazhnyy

machine.hดูเหมือนจะเต็มไปด้วยระบบ ซึ่งmachine.hไฟล์ที่ไม่ได้พึ่งพา?
Roy Hernandez

@ RoyHernandez ทั้งหมดที่ระบุไว้machine.hในระบบของฉันดูเหมือนจะอยู่ใน/usr/src/linux-headers-3.19.0-33ไดเรกทอรี มีโอกาสมากที่จะใช้ไลบรารีที่เคอร์เนลกำลังทำงานอยู่ในขณะนี้
Sergiy Kolodyazhnyy

6

แน่นอนคำตอบของ heemayl นั้นถูกต้อง

เพียงเพื่อความสนุกนี่คือตัวอย่างข้อมูล 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);ดึงข้อมูลมาจากไหน
Roy Hernandez

@RoyHernandez จากที่ struct ซึ่งเป็นประชากรในระหว่างการเรียกร้องให้utsname uname()ตัวอย่างอาจไม่ตรงไปตรงมากับคนที่ไม่มีพื้นฐาน C แต่นี่คือสิ่งที่เกิดขึ้นมากหรือน้อย: มีการประกาศstruct(ประเภทข้อมูล C) ชนิดที่มีutsnameชื่อutsname(กำหนดไว้ในประเภท<sys/utsname.h>); ดังนั้นจึงมีการประกาศตัวชี้ไปยังชื่อutsname_ptr(เนื่องจากuname()ยอมรับตัวชี้structชนิดutsnameที่เป็นอาร์กิวเมนต์แม้ว่าจะสามารถหลีกเลี่ยงได้ในกรณีนี้ แต่เป็นอีกเรื่องหนึ่ง)
kos

จากนั้นการเรียกเพื่อให้uname()มีผลกระทบของการสร้างโครงสร้างutsnameซึ่งในเวลาของการprintf()โทรมีค่าต่างๆภายในเขตข้อมูลต่างๆ อับถ้าคุณไม่คุ้นเคยกับ C นี้อาจจะไม่ให้ง่ายต่อการลงโทษในรายละเอียด แต่ประเด็นก็คือว่าuname()populates printf()โครงสร้างข้อมูลที่สร้างขึ้นบนวัตถุประสงค์ซึ่งสาขาจะมีการพิมพ์ภายหลังผ่าน
kos

4

ที่นอกเหนือไปจากคำตอบ heemayl ของคุณจะได้รับข้อมูลบางอย่างเช่นในคำสั่งจากuname/proc/version


/ proc / version มี "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 "และเอาต์พุต" uname -i "คือ" x86_64 "
Roy Hernandez
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.