답변:
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
구조에 저장된 정보를 검색하라는 sys 호출이 있습니다 . 맨 페이지이며 다음을 제안합니다.
이것은 시스템 호출이며 운영 체제는 아마도 이름, 릴리스 및 버전을 알고있을 것입니다. . . . . . utsname 정보의 일부는 / proc / sys / kernel / {ostype, hostname, osrelease, version, domainname}을 통해 액세스 할 수도 있습니다.
utsname 정보의 일부는 / proc / sys / kernel / {ostype, hostname, osrelease, version, domainname}을 통해 액세스 할 수도 있습니다.
/proc
그러나 파일 시스템은 가상이므로 OS가 실행되는 동안에 만 존재합니다. 따라서 어느 정도 확장하려면 커널 또는 시스템 라이브러리 내에 설정됩니다.
마지막으로 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
디렉토리 에있는 것 같습니다 . 현재 실행중인 커널이 제공하는 라이브러리를 사용하고있을 가능성이 높습니다
물론 헤 마일의 대답은 맞습니다.
재미있게, 여기에 의해 반환 된 데이터 uname()
( uname
원하는 경우 수제 종류)를 보여주는 작동하는 C 스 니펫 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의 기초없이 누군가에게 간단하지만 아니에요 발생하는 다소의하십시오 struct
(C 데이터 형식) 형식의 utsname
이름 utsname
(유형 정의 <sys/utsname.h>
) 선언; 그런 다음 명명 된 포인터 utsname_ptr
가 선언됩니다 ( 이 경우에는 피할 수는 있지만 유형에 uname()
대한 포인터를 인수로 허용하므로 다른 이야기입니다). struct
utsname
uname()
은 struct를 채우는 효과가 utsname
있으며, printf()
호출시 다양한 필드 내부의 다양한 값이 포함됩니다. 불행히도 C에 익숙하지 않다면 아마도 자세히 이해하기 쉽지 않을 것입니다.하지만 요점은 uname()
목적에 따라 작성된 데이터 구조 를 채우고 나중에 필드를 통해 인쇄하는 것 printf()
입니다.
heemayl의 답변에 추가하여에서 uname
명령 과 같은 정보를 얻을 수 있습니다 /proc/version
.