admin管理员组

文章数量:1558087

 前言

        使用uname命令的好处:

        1 使用uname命令可以写出可移植的shell

        2 使用uname命令可以写出可移植的Makefile

        使用uname系统调用的好处:

        使用uname系统调用可以写出可移植的应用程序。

一 uname命令帮助信息

uname --help
root@ATK-IMX6U:~# uname --help
Usage: uname [OPTION]...
Print certain system information.  With no OPTION, same as -s.

  -a, --all                print all information, in the following order,
                             except omit -p and -i if unknown:
  -s, --kernel-name        print the kernel name
  -n, --nodename           print the network node hostname
  -r, --kernel-release     print the kernel release
  -v, --kernel-version     print the kernel version
  -m, --machine            print the machine hardware name
  -p, --processor          print the processor type (non-portable)
  -i, --hardware-platform  print the hardware platform (non-portable)
  -o, --operating-system   print the operating system
      --help     display this help and exit
      --version  output version information and exit

GNU coreutils online help: <http://www.gnu/software/coreutils/>
Full documentation at: <http://www.gnu/software/coreutils/uname>
or available locally via: info '(coreutils) uname invocation'
root@ATK-IMX6U:~#

二 uname命令参数使用

下面测试是在arm系统中完成。

参数-p:获取架构

# uname -p
armv7l

参数 -a:打印所有信息

# uname -a
Linux ATK-IMX6U 4.1.15 #3 SMP PREEMPT Fri Sep 30 11:39:58 CST 2022 armv7l armv7l armv7l GNU/Linux

参数-s:打印内核名字

# uname -s
Linux

参数-n:打印网络节点名字(主机名)

# uname -n
ATK-IMX6U

参数-r:打印内核发布版本

# uname -r
4.1.15

参数-m:打印机器硬件名字

# uname -m
armv7l

参数-v:打印内核的编译时间

# uname -v
#3 SMP PREEMPT Fri Sep 30 11:39:58 CST 2022

参数-i:打印硬件平台

# uname -i
armv7l

参数-o:打印操作系统

# uname -o
GNU/Linux

三 uname系统调用分析

man帮助手册

man 2 uname

$ man 2 uname
       #include <sys/utsname.h>

       int uname(struct utsname *buf);

DESCRIPTION
       uname() returns system information in the structure pointed to by buf.  The utsname struct is defined in <sys/utsname.h>:

           struct utsname {
               char sysname[];    /* Operating system name (e.g., "Linux") */
               char nodename[];   /* Name within "some implementation-defined
                                     network" */
               char release[];    /* Operating system release (e.g., "2.6.28") */
               char version[];    /* Operating system version */
               char machine[];    /* Hardware identifier */
           #ifdef _GNU_SOURCE
               char domainname[]; /* NIS or YP domain name */
           #endif
           };

       The length of the arrays in a struct utsname is unspecified (see NOTES); the fields are terminated by a null byte ('\0').

RETURN VALUE
       On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

ERRORS
       EFAULT buf is not valid.

CONFORMING TO
       POSIX.1-2001, POSIX.1-2008, SVr4.  There is no uname() call in 4.3BSD.

       The domainname member (the NIS or YP domain name) is a GNU extension.

NOTES
       This  is  a  system call, and the operating system presumably knows its name, release and version.  It also knows what hardware it runs on.  So, four of the fields of the struct are meaningful.  On the
       other hand, the field nodename is meaningless: it gives the name of the present machine in some undefined network, but typically machines are in more than one network and have several names.  Moreover,
       the kernel has no way of knowing about such things, so it has to be told what to answer here.  The same holds for the additional domainname field.

       To  this end, Linux uses the system calls sethostname(2) and setdomainname(2).  Note that there is no standard that says that the hostname set by sethostname(2) is the same string as the nodename field
       of the struct returned by uname() (indeed, some systems allow a 256-byte hostname and an 8-byte nodename), but this is true on Linux.  The same holds for setdomainname(2) and the domainname field.

       The length of the fields in the struct varies.  Some operating systems or libraries use a hardcoded 9 or 33 or 65 or 257.  Other  systems  use  SYS_NMLN  or  _SYS_NMLN  or  UTSLEN  or  _UTSNAME_LENGTH.
       Clearly, it is a bad idea to use any of these constants; just use sizeof(...).  Often 257 is chosen in order to have room for an internet hostname.

       Part of the utsname information is also accessible via /proc/sys/kernel/{ostype, hostname, osrelease, version, domainname}.

   C library/kernel differences
       Over  time, increases in the size of the utsname structure have led to three successive versions of uname(): sys_olduname() (slot __NR_oldolduname), sys_uname() (slot __NR_olduname), and sys_newuname()
       (slot __NR_uname).  The first one used length 9 for all fields; the second used 65; the third also uses 65 but adds the domainname field.  The glibc uname() wrapper function hides  these  details  from
       applications, invoking the most recent version of the system call provided by the kernel.

SEE ALSO
       uname(1), getdomainname(2), gethostname(2), namespaces(7)
 

从man帮助信息中提取有用信息

头文件和函数原型

#include <sys/utsname.h>

int uname(struct utsname *buf);

struct utsname {
               char sysname[];    /* Operating system name (e.g., "Linux") */
               char nodename[];   /* Name within "some implementation-defined
                                     network" */
               char release[];    /* Operating system release (e.g., "2.6.28") */
               char version[];    /* Operating system version */
               char machine[];    /* Hardware identifier */
           #ifdef _GNU_SOURCE
               char domainname[]; /* NIS or YP domain name */
           #endif
           };

测试代码

#include <stdio.h>
#include <sys/utsname.h>

int main(int args,char *argv[])
{
        struct utsname ubuf;
        struct utsname *u;
        int ret;
        ret = uname(&ubuf);
        u = &ubuf;
        printf("ret = %d\n",ret);
        printf("sysname = %s\n",u->sysname);
        printf("nodename = %s\n",u->nodename);
        printf("release = %s\n",u->release);
        printf("version = %s\n",u->version);
        printf("machine = %s\n",u->machine);
#ifdef _GNU_SOURCE
        printf("domainname = %s\n",u->domainname);
#else
        printf("nodef _GNU_SOURCE");
#endif
        return 0;
}

ubuntu中测试输出:

$ ./a.out
ret = 0
sysname = Linux
nodename = ubuntu
release = 4.19.260
version = #1 SMP Thu Sep 29 14:19:07 CST 2022
machine = x86_64
nodef _GNU_SOURCE

arm中测试输出

# ./arm_u
ret = 0
sysname = Linux
nodename = ATK-IMX6U
release = 4.1.15
version = #3 SMP PREEMPT Fri Sep 30 11:39:58 CST 2022
machine = armv7l
nodef _GNU_SOURCE

从测试结果得出,通过machine成员判断不同的架构,可以用于通用代码的编写。

总结

        念念不忘必有回响

本文标签: 命令系统uname