답변:
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()대한 포인터를 인수로 허용하므로 다른 이야기입니다). structutsname
uname()은 struct를 채우는 효과가 utsname있으며, printf()호출시 다양한 필드 내부의 다양한 값이 포함됩니다. 불행히도 C에 익숙하지 않다면 아마도 자세히 이해하기 쉽지 않을 것입니다.하지만 요점은 uname()목적에 따라 작성된 데이터 구조 를 채우고 나중에 필드를 통해 인쇄하는 것 printf()입니다.
heemayl의 답변에 추가하여에서 uname명령 과 같은 정보를 얻을 수 있습니다 /proc/version.