博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uname
阅读量:2221 次
发布时间:2019-05-08

本文共 8816 字,大约阅读时间需要 29 分钟。

struct utsname kernel;

 if (uname(&kernel) == -1)

      {
         cmsLog_debug("Failed to get kernel version");
         return CMSRET_INTERNAL_ERROR;
      }

  snprintf(DirPrefix, sizeof(DirPrefix), "/lib/modules/%s/kernel/net", kernel.release);  

      snprintf(moduleName, sizeof(moduleName), "%s.ko", pMod->moduleName);
      snprintf(DirPath, sizeof(DirPath), "%s/%s", DirPrefix, pMod->directory);

 

 

主机信息

正如我们可以确定用户信息一样,程序也可以确定其运行的计算机的信息。uname命令提供了这些信息。uname同时也作为一个系统调用来在一个C程序中提供同样的信息,我们可以使用man 2 uname来查看详细的信息。
许 多情况都需要主机信息。我们也许希望依据在网络中一个程序所运行的机器的名字来自定义其行为,也就是说,是一个学生的机器还是一个管理员的机器。为了授权 的目的,我们也许希望限制一个程序只在一台机器上运行。所有这些都意味着我们需要一个方法来确定程序所运行的机器的信息。
如果系统安装了网络组件,那么我们可以非常容易的通过gethostname函数来得到其网络名:

#include <unistd.h>
int gethostname(char *name, size_t namelen);
gethostname函数将机器的网络名写入name所指的字符串中。假定这个字符串的长度至少为namelen字符长。如果成功,gethostname函数会返回0,否则会返回-1。
我们可以由uname系统调用得到关于主机的更为详细的信息:
#include <sys/utsname.h>
int uname(struct utsname *name);
uname函数将主机信息写入由name参数所指向的结构。utsname结构定义在sys/ustname.h中,大多数至少包含下列成员:
成员        描述
char sysname[]    操作系统名
char nodename[]    主机名
char release[]    系统发行级别
char version[]    系统版本号
char machine[]    硬件类型
如果成功,uname函数会返回一个非负数,否则返回-1,同时设置errno来指示错误。
试验--主机信息
下面是一个程序,hostget.c,来得到主机信息:
#include <sys/utsname.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
    char computer[256];
    struct utsname uts;
    if(gethostname(computer, 255) != 0 || uname(&uts) < 0) {
        fprintf(stderr, “Could not get host information/n”);
        exit(1);
    }
    printf(“Computer host name is %s/n”, computer);
    printf(“System is %s on %s hardware/n”, uts.sysname, uts.machine);
    printf(“Nodename is %s/n”, uts.nodename);
    printf(“Version is %s, %s/n”, uts.release, uts.version);
    exit(0);
}
程序会产生如下的Linux特定的输出。如果我们的机器处在网络中,我们就会发现一个包含网络的扩展主机名:
$ ./hostget
Computer host name is beast
System is Linux on i686 hardware
Nodename is beast
Version is 2.4.19-4GB, #1 Wed Nov 27 00:56:40 UTC 2002
工作原理
这个程序会调用gethostname函数来得到主机的网络名。在前面的例子中,其得到的名字为tilde。更为详细的信息是由unmae函数调用得到的。注意,函数uname所返回的字符串是依赖于实现的;在这个例子中,版本号包含所编译的内核的数据。
由gethostid函数可以得到一个唯一的主机号:
#include <unistd.h>
long gethostid(void);
gethostid函数会返回一个唯一的主机号。授权管理通常使用这个函数来确保软件程序只可以运行一个具有合法授权的机器上。在Sun工作站上,他会返回一个机器在制造时在不可变内存中设置的一个数,所以,对于系统硬件,这是唯一的。
其他的系统,例如Linux,会返回一个基于机器网络地址的值,通常对于授权是足够安全的。
日志
许多程序需要记录他们的动作。系统程序通常将信息写入终端或是一个日志文件。这些信息也许指示错误,警告,或是关于系统状态的更一般的信息。例如,su程序也许会记录一个用户尝试获得超级权限并且失败的事实。
通 常,这些日志信息会记录在一个目录中的一个系统文件中。这也许是/usr/adm或者是/var/log。在通常的Linux安装中, /var/log/messages文件包含系统信息,/var/log/mail包含其他的邮件系统的日志信息,/var/log/debug包含调试 信息。我们可以在/etc/syslog.conf文件中查看我们的系统配置。
如下面的是一些日志信息:
Here are some sample log messages:
   Feb 8 08:38:37     beast kernel: klogd 1.4.1, log source = /proc/kmsg started.
   Feb 8 08:38:37     beast kernel: Inspecting /boot/System.map-2.4.19-4GB
   Feb 8 08:38:37     beast kernel: Loaded 20716 symbols from /boot/System.map-
   2.4.19-4GB.
   Feb 8 08:38:37     beast kernel: Symbols match kernel version 2.4.19.
   Feb 8 08:38:37     beast kernel: Loaded 372 symbols from 17 modules.
   Feb 8 08:38:37 beast kernel: Linux Tulip driver version 0.9.15-pre11 (May 11,
   2002)
Feb 8 08:38:37 beast kernel: PCI: Found IRQ 5 for device 00:0d.0
Feb 8 08:38:37 beast kernel: eth0: ADMtek Comet rev 17 at 0xe400,
00:04:5A:5F:46:52, IRQ 5.
...
Feb  8 08:39:20 beast /usr/sbin/cron[932]: (CRON) STARTUP (fork ok)
Feb  8 09:50:35 beast su: (to root) neil on /dev/pts/4
从这里我们可以看到日志记录的信息。前面的一些是当内核启动并检测安装的硬件时由内核自身报告的。任务调用度器,cron,报告他正是启动。最后,su程序报告用户neil访问一个超级帐户。
一些Unix系统并不会以这种可读的方式提供日志信息,而是提供管理员工具来读取系统事件的数据库。我们可以查看我们的系统文档来得到详细的信息。
尽管系统信息的格式和存储会改变,但是产生这些信息的方法是标准的。Unix系统使用syslog函数来为日志信息的产生提供一个接口:

#include <syslog.h>
void syslog(int priority, const char *message, arguments...);
syslog函数将日志信息发送到日志工具。每一个消息有一个priority参数,他是由安全级别与工具值的位或者到的。安全级别控制这些消息如何产生,而工具值记录消息源。
工具值包括LOG_USER,用来表明消息来自于一个用户程序,LOG_LOCAL0,LOG_LOCAL1直到LOG_LOCAL7,这可以由本地管理员赋于其意义。
下表列出以降序表达的安全级别:
安全级别        描述
LOG_EMERG        一个紧急事件
LOG_ALERT        高优先级问题,例如数据库崩溃
LOG_CRIT        紧急错误,例如硬件失败
LOG_ERR            错误
LOG_WARNING        警告
LOG_NOTICE        需要引起注意的特殊情况
LOG_INFO        信息消息
LOG_DEBUG        调试消息
依据于我们的系统配置,LOG_EMERG消息也许会广播给所有用户,LOG_ALERT消息也许会用邮件发送给管理员,LOG_DEBUG消息会被忽略,而其他的消息会被写入日夜。我们可以编写一个简单的程序,在我们希望创建一个日志消息时可调用syslog日志程序。
由syslog 所创建的日志消息由一个消息头与消息体组成。消息头是由程序指示器与日期和时间创建的。消息体是由到syslog的消息参数创建的,其作用类似于 printf格式化字符串。传递给syslog的其余参数用于在消息字符串中指定printf样式的约定。另外,指示器%m可以用于插入与当前的错误变量 errno相关联的错误消息字符串。这对于记录错误消息十分有用。

试验--syslog
在这个程序中,我们试图打开一个不存在的文件:
#include <syslog.h>
#include <stdio.h>
int main()
{
    FILE *f;
    f = fopen(“not_here”,”r”);
    if(!f)
        syslog(LOG_ERR|LOG_USER,”oops - %m/n”);
    exit(0);
}
当我们编译并运行程序syslog.c时,我们不会看到任何输出,但是文件/var/log/messages中现在却包含下面的记录:
Feb 8 09:59:14 beast syslog: oops - No such file or directory
工作原理
在这个程序中,我们试图打开一个不存在的文件。当操作失败时,我们会看到syslog在系统日志中记录这件事情。
我们可以注意到日志消息并没有指明是哪个程序调用日志程序;他只是记录syslog被一条消息调用的事实。%m格式约定已经被一个错误描述所代替,在这个例子中,这个文件不可以找到。这与只是打印出原始的错误号要有用得多。
在syslog.h中还定义了其他的一些可以用来修改日志程序行为的函数。他们是:

#include <syslog.h>
void closelog(void);
void openlog(const char *ident, int logopt, int facility);
int setlogmask(int maskpri);
我 们可以通过调用openlog函数来修改我们的日志消息所表示的方式。这会让我们设置一个字符串,ident,这会添加到我们日志消息的前面。我们可以使 用他来表明是哪个程序创建这条消息。facility参数记录了一个syslog调用将来要使用的参数值。默认为LOG_USER。logopt参数配置 了将来的syslog调用的行为。他们下面的零个或是多个位或的结果:
logopt参数        描述
LOG_PID            在消息中包含进程标识符,这是由系统分配给进程的唯一标识号
LOG_CONS        如果消息不可以被记录就发送到终端
LOG_ODELAY        在第一次调用时打开log程序
LOG_NDELAY        立即打开log程序,而不是第一次调用时
openlog函数会分配并且打开一个用于写入日志程序的文件描述符。我们可以调用closelog函数将其关闭。注意,在调用syslog函数之前并不需要调用openlog,因为syslog本身会在需要的时候打开。
我们可以使用setlogmask函数来设置日志掩码从而控制我们日志消息的优先级别。以后那些使用在日志掩码中没有设置的优先级调用syslog函数都会被拒绝,例如,我们可以使用这个方法关闭LOG_DEBUG消息,而不需要修改程序体。
我们可以使用LOG_MASK(priority)来为日志消息创建掩码,这会创建一个只包含一个优先级的掩,或是LOG_UPTO(priority),这会创建一个包含直到priority且包含priority的所有优先级的掩码。
试验--logmask
在这个例子,我们会实际的看一下logmask的使用:
#include <syslog.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    int logmask;
    openlog(“logmask”, LOG_PID|LOG_CONS, LOG_USER);
    syslog(LOG_INFO,”informative message, pid = %d”, getpid());
    syslog(LOG_DEBUG,”debug message, should appear”);
    logmask = setlogmask(LOG_UPTO(LOG_NOTICE));
    syslog(LOG_DEBUG,”debug message, should not appear”);
    exit(0);
}
这个logmask.c程序并不会产生任何输出,但是在特定的Linux系统上,在/var/log/messages的结束处,我们会看到下面的行:
Feb 8 10:00:50 beast logmask[1833]: informative message, pid = 1833
配置用来接收调试日志消息的文件应包含下面的行:
Feb 8 10:00:50 beast logmask[1833]: debug message, should appear
工作原理
程 序使用他的名字,logmask来初始化日志程序,并且请求消息中包含进程标识符。信息消息被记录到/var/log/messages,而调试信息记录 到/var/log/debug文件中。第二个调试信息并不会出现,因为我们调用setlogmask函数忽略了所有优先级小于LOG_NOTICE的消 息。
如果我们的安装没有记录调试信息的功能,或者是进行了不同的配置,那么我们也许不会看到调试消息的输出。为了允许所有的调试消息,在/etc/syslog.conf的最后加入下面一行并重启。然而,一定要查看我们的系统文档来得到确切的配置方法:
*.debug /var/log/debug
logmask.c使用了getpid函数,他与其相关的getppid的函数定义如下:
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
这两个函数会返回调用进程的及其父进程的进程标识符。要了解更多的关于PID的内容,可以查看第11章。

 

 

uname 是Linux命令

  用途

  显示当前操作系统名称。

  语法

  uname [ -a | -x | -S Name ] [ -F ] [ -f ] [ -l ] [ -L ] [ -m ] [ -M ] [ -n ] [ -p ] [ -r ] [ -s ] [ -T Name ] [ -u ] [ -v ]

  描述

  uname 命令将正在使用的操作系统名写到标准输出中。

  机器 ID 号码包括以下数字格式的 12 个字符 xxyyyyyymmss。xx 位置指示系统且始终为 00。yyyyyy 位置包含整个系统的唯一标识号。mm 位置代表型号标识。ss 位置为子型号并且始终为 00。型号标识描述 CPU 平板标识,而不是描述整个系统的型号。

  有时可使用 uname -m 命令决定使用什么型号。以下列表并非全面。参考硬件供应商提供的文档以获取 E0-FF 范围内的值。并且注意并非所有的机器类型都有机器 ID。许多新机器都共享 4C 的公共机器 ID。系统型号十六进制代码(mm)为:

  机器 机器 机器

  类型 型号 标识

  7006 410 42

  7007 N40 F0

  7008 M20 43

  7008 M20A 43

  7009 C10 48

  7011 220 41

  7011 230 47

  7011 250 46

  7012 320 31

  7012 320H 35

  7012 340 37

  7012 350 38 或 77

  7012 355 77

  7012 360 76

  7012 365 76

  7012 370 75

  7012 375 75

  7012 380 58

  7012 390 57

  7012 G30 A6

  7012 G40 A7

  7013 520 30

  7013 520H 34

  7013 530 10

  7013 530H 18

  7013 540 14 或 11

  7013 550 1C

  7013 550L 77

  7013 560 5C

  7013 570 67

  7013 580 66

  7013 58H 71

  7013 590 70

  7013 590H 72

  7013 J30 A0

  7013 J40 A1

  7015 930 20 或 02

  7015 950 2E

  7015 970 63

  7015 970B 63

  7015 980 64

  7015 980B 64

  7015 990 80

  7015 R10 67

  7015 R20 72

  7015 R24 81

  7015 R30 A3

  7015 R40 A4

  7016 730 10

  7018 740 30

  7018 770 67

  7024 E20 C0

  7025 F30 C4

  7030 3AT 58

  7030 3BT 57

  7043 140 4C

  7043 240 4C

  7248 43P 4C

  当安装了新的操作系统软件级别时, uname 命令返回的机器标识符值可能改变。这一改变影响使用该值访问许可程序的应用程序。需要查看标识符,输入 uname -m 命令。

  如果应用程序受到影响,联系合适的支持组织。

  标志

  -a         显示 -m、 -n、 -r、 -s 和 -v 标志指定的所有信息。不能与 -x 或 -SName 标志连用。如果 -x 标志和 -a 标志一起指定,-x 标志会覆盖它。

  -F         显示由十六进制字符构成的系统标识字符串。此标识字符串对特定系统上的所有分区都是相同的。

  -f         除分区号还用于此字符串的计算之外,与 F 标志类似。产生的标识字符串对特定系统上的每个分区都是唯一的。

  -l         显示 LAN 网络号码。

  -L         显示 LPAR 号码和 LPAR 名称。如果 LPAR 不存在,“-1”显示为 LPAR 号码,NULL 为 LPAR 名称

  -m         显示硬件运行系统的机器 ID 号。

  注:

  -m 标志不能为 LPAR 环境中的分区生成唯一的机器标识。

  -M         显示系统型号名称。如果型号名称属性不存在,显示空字符串

  -n         显示节点名称。可能是用以标识系统且为 UUCP 通信网络所知的名称。

  -p         显示系统处理器的体系结构。

  -r         显示操作系统的发行版号。

  -s         显示系统名。标志缺省为开。

  -S Name         设置节点名。可以是系统 UUCP 通信网络名。

  -T Name         设置系统名。可以是系统 UUCP 通信网络名。

  -u         显示系统 ID 号码。如果这一属性未被定义,输出与 uname -m显示的输出一致。

  -v         显示操作系统版本。

  -x         显示 -a 标志指定的信息和 -l 标志指定的 LAN 网络号。

  如果输入标志无效, uname 命令退出,生成错误消息、错误返回状态,并无输出。

  注意:经过系统重新引导后,“uname”命令不保存新系统名和节点名称值。

  退出状态

  该命令返回以下退出值:

  0         请求信息成功写入。

  >0         发生错误。

  示例

  显示完整系统名和版本栏,输入:

  uname -a

  文件

  /usr/bin/uname         包含 uname 命令。

转载地址:http://jenfb.baihongyu.com/

你可能感兴趣的文章
【LEETCODE】204-Count Primes
查看>>
【LEETCODE】228-Summary Ranges
查看>>
【LEETCODE】27-Remove Element
查看>>
【LEETCODE】66-Plus One
查看>>
【LEETCODE】26-Remove Duplicates from Sorted Array
查看>>
【LEETCODE】118-Pascal's Triangle
查看>>
【LEETCODE】119-Pascal's Triangle II
查看>>
【LEETCODE】190-Reverse Bits
查看>>
【LEETCODE】67-Add Binary
查看>>
【LEETCODE】223-Rectangle Area
查看>>
【LEETCODE】12-Integer to Roman
查看>>
【学习方法】如何分析源代码
查看>>
【LEETCODE】61- Rotate List [Python]
查看>>
【算法】- 动态规划的编织艺术
查看>>
用 TensorFlow 让你的机器人唱首原创给你听
查看>>
深度学习的主要应用举例
查看>>
word2vec 模型思想和代码实现
查看>>
怎样做情感分析
查看>>
用深度神经网络处理NER命名实体识别问题
查看>>
用 RNN 训练语言模型生成文本
查看>>