09 系统数据文件和信息

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_29350001/article/details/69526361

UNIX 系统的正常运作需要使用大量与系统有关的数据文件,例如,口令文件 /etc/passwd 和组文件 /ect/group 就是经常被多个程序频繁使用的两个文件。用户每次登陆 UNIX 系统,以及每次执行 ls -l 命令时都要使用口令文件。

一、口令文件

1、口令文件简介

UNIX 系统口令文件包含的字段,而这些字段包含在 /usr/include/pwd.h 中的定义的 passwd 结构中

    
    
  1. /* The passwd structure. */
  2. struct passwd
  3. {
  4. char *pw_name; /* Username. */
  5. char *pw_passwd; /* Password. */
  6. __uid_t pw_uid; /* User ID. */
  7. __gid_t pw_gid; /* Group ID. */
  8. char *pw_gecos; /* Real name. */
  9. char *pw_dir; /* Home directory. */
  10. char *pw_shell; /* Shell program. */
  11. };
由于历史原因,口令文件是 /etc/passwd,而且是一个 ASCII 文件。
这部分讲过,这话说的我都自信满满了。参看:Hi3516A开发--/etc/passwd

    
    
  1. # cat /etc/passwd
  2. root:x: 0: 0:root:/root:/bin/bash
  3. tarena:x: 1000: 1000:tarena,,,:/home/tarena:/bin/bash
  4. nobody:x: 65534: 65534:nobody:/nonexistent:/bin/sh
各字段含义就不讲了,关于这些登录项,请注意下列各点:
(1)通常有一个用户名为 root 的登录项,其用户 ID 是 0(超级用户)
(2)加密口令字段包含了一个占位符。
(3)口令文件项中的某些字段可能是空。
(4)shell 字段包含了一个可执行程序名,它被用作该用户的登录 shell
(5)阻止一个特定用户登录系统的方法:
       使用 /dev/null
       将 /bin/false 用作登录 shell。它简单地以不成功(非 0)状态终止,该 shell 将此种状态判断位假。
       用 /bin/true 禁止一个账户。它所做的一切是以成功(0)状态终止。
(6)使用 nobody 用户名的目的是,使任何人都可以登录至系统,但其用户 ID (65534)和组 ID(65534)不提供任何特权。该用户 ID 和组 ID只能访问人人皆可读、写的文件。
(7)提供 finger 命令的某些 UNIX 系统支持注释字段中的附加信息。

    
    
  1. # finger -p tarena
  2. Login: tarena Name: tarena
  3. Directory: /home/tarena Shell: /bin/bash
  4. Last login Tue Aug 2 11: 40 2016 (CST) on pts/ 3 from ubuntu.local
  5. No mail.
POSIX.1 定义了两个获取口令文件项的函数,在给出用户登录名或者数值用户ID后,这两个函数就能查询相关项

2、函数 getpwuid 和 getpwnam


    
    
  1. #include <pwd.h>
  2. struct passwd *getpwuid(uid_t uid);
  3. struct passwd *getpwnam(const char *name);

(1)函数解析

这两个函数都返回一个指向 passwd 结构的指针,该结构已由这两个函数在执行时填入信息。passwd 结构通常是函数内部的静态变量,只要调用任一相关函数,其内容就会被重写。

(2)示例说明


     
     
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <pwd.h>
  4. int main (void)
  5. {
  6. struct passwd *pwd;
  7. if ((pwd = getpwuid ( 1000)) == NULL)
  8. perror ( "fail to getpwuid"), exit ( 1);
  9. printf( "%s,%s,%ld,%ld,%s,%s,%s\n",pwd->pw_name, pwd->pw_passwd,
  10. pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell);
  11. if ((pwd = getpwnam ( "tarena")) == NULL)
  12. perror ( "fail to getpwnam"), exit ( 1);
  13. printf( "%s,%s,%ld,%ld,%s,%s,%s\n",pwd->pw_name, pwd->pw_passwd,
  14. pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell);
  15. return 0;
  16. }
  17. 输出结果:
  18. tarena,x, 1000, 1000,tarena,,,,/home/tarena,/bin/bash
  19. tarena,x, 1000, 1000,tarena,,,,/home/tarena,/bin/bash

3、函数 getpwent、setpwent 和 endpwent


    
    
  1. #include <pwd.h>
  2. struct passwd* getpwent(void);
  3. void setpwent(void);
  4. void endpwent(void);

(1)函数解析

用于查看 登录名和用户 ID。
调用 getpwent 时,它返回口令文件中的下一个记录项。它返回一个由它填写好的 passwd 结构的指针。每次调用此函数时都重写该结构。在第一次调用该函数时,它打开所使用的各个文件。在使用本函数时,对口令文件中各个记录项的安排顺序并无要求。某些系统采用散列算法对 /etc/passwd 文件中各项排序。
函数 setpwent 反绕它所使用的文件,endpwent 则关闭这些文件。在使用 getpwent 查看完口令文件后,一定要调用 endpwent 关闭这些文件。getpwent 知道什么时间应当打开它所使用的文件(第一次被调用时),但是它并不知道何时关闭这些文件。

(2)示例说明


    
    
  1. #include <pwd.h>
  2. #include <sys/types.h>
  3. #include <stdio.h>
  4. int main (void)
  5. {
  6. struct passwd *user;
  7. setpwent ();
  8. while ((user = getpwent ()) != NULL)
  9. {
  10. if ( strcmp ( "tarena", user->pw_name) == 0)
  11. break;
  12. }
  13. printf ( "%s:%d:%d:%s:%s:%s\n",user->pw_name,user->pw_uid,user->pw_gid,
  14. user->pw_gecos,user->pw_dir,user->pw_shell);
  15. endpwent ();
  16. return 0;
  17. }
  18. 输出结果:
  19. tarena: 1000: 1000:tarena,,,:/home/tarena:/bin/bash

(3)示例总结

在函数开始处调用 setpwent 是自我保护性的措施,以便确保如果调用者在此之前已经调用 getpwent 打开了有关文件情况下,反绕有关文件使他们定位到文件开始处。getpwnam 和 getpwuid 完成后不应使有关文件仍处于打开状态。所以应调用 endpwent 关闭它们。
简单来说, setpwent 可以定位到文件开始处。如果不使用 setpwent 的情况下举个例子:

    
    
  1. #include<pwd.h>
  2. #include<sys/types.h>
  3. #include <stdio.h>
  4. int main (void)
  5. {
  6. struct passwd *user;
  7. int i;
  8. for(i = 0; i < 4; i++) {
  9. user = getpwent ();
  10. printf ( "%s :%d :%d :%s:%s:%s\n", user->pw_name, user->pw_uid, user->pw_gid,
  11. user->pw_gecos, user->pw_dir, user->pw_shell);
  12. }
  13. // setpwent();
  14. user = getpwent ();
  15. printf ( "=============================\n");
  16. printf ( "%s :%d :%d :%s:%s:%s\n", user->pw_name, user->pw_uid, user->pw_gid,
  17. user->pw_gecos, user->pw_dir, user->pw_shell);
  18. endpwent();
  19. return 0;
  20. }
  21. 输出结果:
  22. root : 0 : 0 :root:/root:/bin/bash
  23. daemon : 1 : 1 :daemon:/usr/sbin:/bin/sh
  24. bin : 2 : 2 :bin:/bin:/bin/sh
  25. sys : 3 : 3 :sys:/dev:/bin/sh
  26. =============================
  27. sync : 4 : 65534 :sync:/bin:/bin/sync

二、阴影口令

加密口令是经单向加密算法处理过的用户口令副本。因为此算法是单向的,所以不能从加密口令猜测到原来的口令。
现在,某些系统将加密口令存放在令一个通常称为阴影口令文件中。该文件至少要包含用户名和加密口令。与该口令相关的其他信息也可存放在该文件中。
阴影口令包含的字段包含在 /usr/include/shadow.h 中的定义的 spwd 结构中。

    
    
  1. /* Structure of the password file. */
  2. struct spwd
  3. {
  4. char *sp_namp; /* Login name. */
  5. char *sp_pwdp; /* Encrypted password. */
  6. long int sp_lstchg; /* Date of last change. */
  7. long int sp_min; /* Minimum number of days between changes. */
  8. long int sp_max; /* Maximum number of days between changes. */
  9. long int sp_warn; /* Number of days to warn user to change
  10. the password. */
  11. long int sp_inact; /* Number of days the account may be
  12. inactive. */
  13. long int sp_expire; /* Number of days since 1970-01-01 until
  14. account expires. */
  15. unsigned long int sp_flag; /* Reserved. */
  16. };
阴影口令文件是 /etc/shadow

    
    
  1. # cat /etc/shadow
  2. root:$ 6$MNQKabSO$UcLm09JPH7JdppbRZBrj4XoWUQIWRhqhwdzJ9F2mGlwSXo5V.ylP4.gaReQSw3sZSSuczM1iqnMKBrwnbDlgz/: 17131: 0: 99999: 7:::
  3. tarena:$ 6$kea9L4dJ$PeK8uyZ8MesNW6zG1fMMnJIol4icj0nLKAg7Vq78sLJJhEs1Sr6M/VpxBvy.kGeMVDr2SC/EN8Utx5OSIx8Fs/: 16630: 0: 99999: 7:::
  4. nobody:*: 15453: 0: 99999: 7:::

1、阴影口令函数


    
    
  1. #include <shadow.h>
  2. struct spwd *getspnam(const char *name);
  3. struct spwd *getspent(void);
  4. void setspent(void);
  5. void endspent(void);
  6. 返回值:成功返回指针,失败返回 NULL

(1)函数功能

getspnam,访问 shadow 口令。
getspent,是获得访问影子密码文件的接口。

(2)示例说明


    
    
  1. #include <stdio.h>
  2. #include <shadow.h>
  3. #include <stdlib.h>
  4. int main (void)
  5. {
  6. struct spwd* spwd;
  7. if ((spwd = getspnam( "tarena")) == NULL)
  8. perror( "getspnam"), exit ( 1);
  9. printf( "%s,%s,%ld,%ld,%ld,%ld,%ld,%ld,%lu\n",spwd->sp_namp,spwd->sp_pwdp,spwd->sp_lstchg,
  10. spwd->sp_min,spwd->sp_max,spwd->sp_warn,spwd->sp_inact,spwd->sp_expire,spwd->sp_flag);
  11. setspent();
  12. while ((spwd = getspent()) != NULL)
  13. {
  14. if ( strcmp ( "tarena", spwd->sp_namp) == 0)
  15. break;
  16. }
  17. printf( "%s,%s,%ld,%ld,%ld,%ld,%ld,%ld,%lu\n",spwd->sp_namp,spwd->sp_pwdp,spwd->sp_lstchg,
  18. spwd->sp_min,spwd->sp_max,spwd->sp_warn,spwd->sp_inact,spwd->sp_expire,spwd->sp_flag);
  19. endspent();
  20. return 0;
  21. }
  22. 输出结果:
  23. tarena,$ 6$kea9L4dJ$PeK8uyZ8MesNW6zG1fMMnJIol4icj0nLKAg7Vq78sLJJhEs1Sr6M/VpxBvy.kGeMVDr2SC/EN8Utx5OSIx8Fs/, 16630, 0, 99999, 7, -1, -1, 4294967295
  24. tarena,$ 6$kea9L4dJ$PeK8uyZ8MesNW6zG1fMMnJIol4icj0nLKAg7Vq78sLJJhEs1Sr6M/VpxBvy.kGeMVDr2SC/EN8Utx5OSIx8Fs/, 16630, 0, 99999, 7, -1, -1, 4294967295

2、思考

这让我想起,在Ubuntu 10.04版本上,设置 超级用户 root 登录密码了。

    
    
  1. $sudo passwd root
  2. Enter new UNIX password: <--- 新的Root用户
  3. Password: <--- 输入你当前用户davinci的密码
  4. 密码
  5. Retype new UNIX password: <--- 重复新的Root用户密码
  6. passwd:已成功更新密码

(1)可以写个程序验证密码是不是 root:


     
     
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. int main(void)
  5. {
  6. char *passwd;
  7. char key[] = "root";
  8. passwd = crypt(key, "$6$MNQKabSO$");
  9. printf( "root: %s\n", passwd);
  10. return 0;
  11. }
  12. 编译:gcc test -lcrypt
  13. 输出结果:
  14. root: $ 6$MNQKabSO$UcLm09JPH7JdppbRZBrj4XoWUQIWRhqhwdzJ9F2mGlwSXo5V.ylP4.gaReQSw3sZSSuczM1iqnMKBrwnbDlgz/

(2)示例总结

该示例证明,我的超级用户 root的密码确实是 root。 注意到示例中出现了一个新的函数 crypt。

    
    
  1. #define _XOPEN_SOURCE /* See feature_test_macros(7) */
  2. #include <unistd.h>
  3. char *crypt(const char *key, const char *salt);
  4. #define _GNU_SOURCE /* See feature_test_macros(7) */
  5. #include <crypt.h>
  6. char *crypt_r(const char *key, const char *salt, struct crypt_data *data);
  7. Link with -lcrypt.
  8. 返回值:返回一个以 NULL 结尾的密码字符串
注意,编译时需要链接 -lcrypt,否则会出现 undefined reference to `crypt' 错误。
1)参数解析
第一个参数:要加密的明文。
必需。规定要编码的字符串。
第二个参数:密钥
可选。用于增加被编码字符数目的字符串,以使编码更加安全。如果未提供 salt 参数,则每次调用该函数时会随机生成一个。
(1)salt 这个字符串如果以$1$开头,以$结尾,那么这表示让crypt用MD5的方式加密,加密后出来的密文格式就
是 $1$...$<密文正文> ,夹在$1$和$之间的字符串就是我们指定的密钥文字。这个密钥文字最多不能超过8个字符。
(2)如果salt字符串不是(1)方式的格式,那默认就用DES加密方法。DES加密时,salt只能取两个字符,也就是
说,salt最多不能 超过2个字符,多出的字符会被丢弃,用DES加密出来的密文前两个字符就是密钥。后面紧跟着的
就是真正的密文。
(3)参数 salt 为两个字符组成的字符串,由 a-z,A-Z,0-9,".",和 "/" 所组成。
2)函数功能
crypt() 函数返回加密的字符串。 它使用的是一种单向算法。解密函数是没有的。

扩展:getpass 函数通常会与 crypt 加密函数一同使用

    
    
  1. #include <unistd.h>
  2. char *getpass( const char *prompt);
函数功能:
getpass() 函数用于从控制台输入一行字符串,关闭了回显(输入时不显示输入的字符串),适用于用密码的输入。
函数说明:
getpass() 会显示参数 prompt 所指的字符串,然后从 /dev/tty 中读取所输入的密码,若无法从 /dev/tty 中读取则会转从标准输入设备中读取密码。所输入的密码长度限制在 128 个字符,包含结束字符 NULL, 超过长度的字符及换行字符 /n 将会被忽略。在输入密码时 getpass() 会关闭字符回应,并忽略一些信号如 CTRL-C 或 CTRL-Z 所产生的信号
返回值:
返回一个指向以NULL结尾的密码字符串
附加说明:
为了系统安全考虑,在般在使用getpass()输入密码后,该密码最好尽快处理完毕,然后将该密码字符串清除
示例说明:

    
    
  1. //示例一
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <sys/types.h>
  8. #include <sys/wait.h>
  9. #include <crypt.h>
  10. int main()
  11. {
  12. char passwd[ 13];
  13. char *key;
  14. char slat[ 2];
  15. key = getpass( "Input first passward:");
  16. slat[ 0] = key[ 0];
  17. slat[ 1] = key[ 1];
  18. strcpy(passwd,crypt(key,slat));
  19. key = getpass( "Input second passward:");
  20. slat[ 0] = passwd[ 0];
  21. slat[ 1] = passwd[ 1];
  22. printf( "After crypt(),1st passwd:%s\n",passwd);
  23. printf( "After crypt(),2st passwd:%s\n",passwd);
  24. return 0;
  25. }
  26. 编译:
  27. # gcc test.c -lcrypt
  28. 输出结果:
  29. Input first passward: //root
  30. Input second passward: //root
  31. After crypt(),1st passwd:roK20XGbWEsSM
  32. After crypt(),2st passwd:roK20XGbWEsSM

三、组文件

UNIX 组文件包含的字段包含在 /usr/include/grp.h 中所定义的 group 结构中。

     
     
  1. /* The group structure. */
  2. struct group
  3. {
  4. char *gr_name; /* Group name. */
  5. char *gr_passwd; /* Password. */
  6. __gid_t gr_gid; /* Group ID. */
  7. char **gr_mem; /* Member list. */
  8. };
其中,字段 gr_mem 是一个指针数组,其中每个指针指向一个属于该组的用户名。该数组以 null 指针结尾。
组文件是 /etc/group

     
     
  1. # cat /etc/group
  2. root:x: 0:
  3. tarena:x: 1000:
对组文件的访问函数如下,形式基本与口令文件和阴影文件相同。

     
     
  1. #include <grp.h>
  2. struct group *getgrgid(gid_t gid);
  3. struct group *getgrnam(const char *name);
  4. //两个函数返回值:如果成功返回指针,出错则返回NULL。
  5. struct group *getgrent(void); //如果成功返回指针,出错或者到达文件结尾则返回NULL
  6. void setgrent(void);
  7. void endgrent(void);

四、附属组 ID

我们不仅可以属于口令文件记录项中组 ID 所对应的组,也可属于多至 16 个另外的组。文件访问权限检查相应被修改为:不仅将进程的有效组 ID 相计较,而且也将所有附属组 ID 与文件的组 ID 进行比较。
为了获取和设置附属组 ID,提供了下列 3 个函数。

     
     
  1. #include <sys/types.h>
  2. #include <unistd.h>
  3. int getgroups(int size, gid_t list[]);
  4. #include <grp.h>
  5. int setgroups(size_t size, const gid_t *list);
  6. Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
  7. setgroups (): _BSD_SOURCE
  8. #include <sys/types.h>
  9. #include <grp.h>
  10. int initgroups (const char *user, gid_t group);
  11. Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
  12. initgroups (): _BSD_SOURCE

1、函数解析

(1)getgroups 将进程所属用户的各附属组 ID 填写到数组 grouplist 中,填写入数组的附属组 ID 数最多为 gidsetsize 个。实际填写到数组中的附属组 ID 数由函数返回。
返回值:成功返回附属组 ID 数量,若出错,返回 -1.
(2)setgroups 由root调用,为进程设置附加组ID表,grouplist是组ID数组,ngroups指定了数组中的元素个数。
返回值:如果成功返回0,出错则返回-1.
(3)initgroups 用来从组文件(/etc/group)读取整个组文件,然后对username确定其组的成员关系,然后调用setgroups。 为该用户初始化附加组ID表。除了在组文件中找到username是成员的所有组,initgroups也在附加组ID表中包括了  basegid,basegid是username在口令文件中的组ID。
返回值:如果成功返回0,出错则返回-1.

五、其他数据文件

一般情况下,对于每个数据文件至少有 3 个函数:
(1)get 函数:读下一个记录,如果需要,还会打开该文件。此种函数通常返回指向一个结构的指针。当已达到文件尾端时返回空指针。大多数 get 函数返回指向一个静态存储类结构的指针,如果要保存其内容,则需复制它。
(2)set 函数:打开相应数据文件(如果尚未打开),然后反绕该文件。如果希望在相应文件起始处开始处理,则调用此函数。
(3)end 函数:关闭相应数据文件。如前所述,在结束了对应数据文件的读、写操作后,总应调用此函数以关闭相关文件。
下面列出了 UNIX 常用的文件对应的函数:

六、系统标识

1、uname 函数,返回与主机和操作系统有关的信息。


    
    
  1. #include <sys/utsname.h>
  2. int uname(struct utsname * name);
  3. 返回值:成功返回非负值,失败返回 -1

(1)参数解析

通过该函数的参数向其传递一个 utsname 结构的地址,然后该函数填写此结构。
其结构定义在 /usr/include/i386-linux-gnu/sys/utsname.h 

    
    
  1. /* Structure describing the system and machine. */
  2. struct utsname
  3. {
  4. /* Name of the implementation of the operating system. */
  5. char sysname[_UTSNAME_SYSNAME_LENGTH];
  6. /* Name of this node on the network. */
  7. char nodename[_UTSNAME_NODENAME_LENGTH];
  8. /* Current release level of this implementation. */
  9. char release[_UTSNAME_RELEASE_LENGTH];
  10. /* Current version level of this release. */
  11. char version[_UTSNAME_VERSION_LENGTH];
  12. /* Name of the hardware type the system is running on. */
  13. char machine[_UTSNAME_MACHINE_LENGTH];
  14. #if _UTSNAME_DOMAIN_LENGTH - 0
  15. /* Name of the domain of this node on the network. */
  16. # ifdef __USE_GNU
  17. char domainname[_UTSNAME_DOMAIN_LENGTH];
  18. # else
  19. char __domainname[_UTSNAME_DOMAIN_LENGTH];
  20. # endif
  21. #endif
  22. };

(2)示例说明

每个字符串都以 null 字节结尾。

      
      
  1. #include <stdio.h>
  2. #include <sys/utsname.h>
  3. #include <stdlib.h>
  4. int main (void)
  5. {
  6. struct utsname uts;
  7. if (uname (&uts) == -1)
  8. perror ( "fail to uname"), exit ( 1);
  9. else
  10. printf ( "%s %s %s %s %s\n", uts.sysname, uts.nodename,
  11. uts.release, uts.version, uts.machine);
  12. return 0;
  13. }
  14. 输出结果:
  15. Linux ubuntu 3.2 .0 -23-generic-pae # 36-Ubuntu SMP Tue Apr 10 22: 19: 09 UTC 2012 i686

(3)Linux 下的 uname 命令

uname 命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。
选项:

    
    
  1. -a或--all:显示全部的信息;
  2. -m或--machine:显示电脑类型;
  3. -n或-nodename:显示在网络上的主机名称;
  4. -r或--release:显示操作系统的发行编号;
  5. -s或--sysname:显示操作系统名称;
  6. -v:显示操作系统的版本;
  7. -p或--processor:输出处理器类型或 "unknown"
  8. -i或--hardware-platform:输出硬件平台或 "unknown"
  9. -o或--operating-system:输出操作系统名称;
  10. --help:显示帮助;
  11. --version:显示版本信息。
示例:

    
    
  1. # uname -a
  2. Linux ubuntu 3.2 .0 -23-generic-pae # 36-Ubuntu SMP Tue Apr 10 22: 19: 09 UTC 2012 i686 i686 i386 GNU/Linux

2、gethostname 函数


    
    
  1. #include <unistd.h>
  2. int gethostname(char * name, int namelen);
  3. 返回:若成功则为 0,若出错则为 -1

(1)函数解析

该函数只返回主机名,该名字通常是 TCP/IP 网络上主机的名字。
namelen 参数指定 name 缓冲区长度,如若提供足够的空间,则通过 name 返回的字符串以 null 字节结尾。如若没有提供足够的空间,则没有说明通过 name 返回的字符串是否以 null 结尾。
现在,gethostname 函数已在 POSIX.1 中定义,它指定的最大主机名长度是 HOST_NAME_MAX 不小于255

     
     
  1. HOST_NAME_MAX - _SC_HOST_NAME_MAX
  2. Max length of a hostname, not including the terminating null byte, as returned by gethostname(2). Must not be less than _POSIX_HOST_NAME_MAX (255).
uname 函数,查看结果为:#define _UTSNAME_LENGTH 65  即最大名字长度为 65

     
     
  1. # grep "_UTSNAME_LENGTH" * -rn
  2. i386-linux-gnu/sys/utsname.h: 33: # define _UTSNAME_SYSNAME_LENGTH _UTSNAME_LENGTH
  3. i386-linux-gnu/sys/utsname.h: 36: # define _UTSNAME_NODENAME_LENGTH _UTSNAME_LENGTH
  4. i386-linux-gnu/sys/utsname.h: 39: # define _UTSNAME_RELEASE_LENGTH _UTSNAME_LENGTH
  5. i386-linux-gnu/sys/utsname.h: 42: # define _UTSNAME_VERSION_LENGTH _UTSNAME_LENGTH
  6. i386-linux-gnu/sys/utsname.h: 45: # define _UTSNAME_MACHINE_LENGTH _UTSNAME_LENGTH
  7. i386-linux-gnu/sys/utsname.h: 77: # define SYS_NMLN _UTSNAME_LENGTH
  8. i386-linux-gnu/bits/utsname.h: 24: #define _UTSNAME_LENGTH 65
  9. i386-linux-gnu/bits/utsname.h: 29: #define _UTSNAME_DOMAIN_LENGTH _UTSNAME_LENGTH

(2)示例说明


     
     
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. int main (void)
  4. {
  5. char name[ 65];
  6. gethostname(name, sizeof(name));
  7. printf( "hostname = %s\n", name);
  8. return 0;
  9. }
  10. 输出结果:
  11. hostname = ubuntu

(3)Linux 下的 hostname 命令

hostname 命令用于显示和设置系统的主机名称。环境变量 HOSTNAME 也保存了当前的主机名。在使用 hostname 命令设置主机名后,系统并不会永久保存新的主机名,重新启动机器之后还是原来的主机名。如果需要永久修改主机名,需要同时修改/etc/hosts和/etc/sysconfig/network的相关内容
选项:

     
     
  1. -v:详细信息模式;
  2. -a:显示主机别名;
  3. -d:显示DNS域名;
  4. -f:显示FQDN名称;
  5. -i:显示主机的ip地址;
  6. -s:显示短主机名称,在第一个点处截断;
  7. -y:显示NIS域名。
示例:

     
     
  1. # hostname
  2. ubuntu

七、时间和日期例程

参看:C语言再学习 -- 时间函数

八、未讲部分

组文件 (简单介绍)
附属组 ID (简单介绍)
登录账户记录
时间和日期例程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值