linux系统编程 获取系统信息

一、本章讲什么

1.1 获取系统文件的数据

(1)什么是系统文件

			就是Linux系统自己会用到的文件,分为两类。
			
			
	1)文本文件
	(a)里面的内容都是文字编码,vi打开后,我们能够识别的数据。

	
	(b)放的都是Linux系统要用到各种配置信息
			Linux系统在启动和运行时,会用到里面的数据。
		
			我们自己写的程序,有的时候也需要用到里数据,但是我们基本只是读数据,大多数
		情况只有Linux系统才会去改里面的数据,本章会介绍我们自己的程序,如何来调用API
		来获取里面的数据。
			
			
	(c)比如后面要讲的/etc/passwd文件
			里面放的是用户的账户信息。
			
			用户登录系统时,输入用户名和密码后,Linux会使用你输入的用户名和密码,然后到这个
		文件中匹配注册的用户名和密码,只有匹配成功后才能登录,否者你是登录不了的。

			
	(d)文本形式的系统文件,大多放在了/etc这个目录下
			本站要介绍的系统文件,都是/etc/下的文件。

				
			
	2)纯二进制文件
	
		(a)比如各种编译好的库、以及可执行文件,里面放是能够被cpu执行的机器指令。
					
				· 库的话,都放在了各种名叫lib的目录下,比如/lib,lib就是库的意思。
					
						其实有好多lib目录,比如/lib、/usr/lib等,有关它们的区别,本门课
					暂不介绍,后面讲《Linux基础高级》时会详说。
					
					
				· 各种可执行文件的话
					
					比如ls、mkdir等这些命令(可执行程序),都放在了各种名叫bin的目录下,
				比如/bin,bin就是binary二进制的意思。
					
					bin目录也有好些,比如/bin,/usr/bin,同样的,有关它们的区别,本门课
				暂不介绍,后面讲《Linux基础高级》时会详说。
					
					
		(b)二进制文件,我们vi后是看不懂的
				因为里面放的不是文字编码,所以文本编辑器无法正确翻译为文字图形,所以我们无法看懂。
				
			

	3)系统文件的特点
				
				
		(a)系统文件的所属用户都是root,所属组也基本都是root。
					演示:

					
		(b)普通用户操作系统文件时,只能以其它用户的身份去操作,而其它用户的权限往往只有r,
		所以普通不能写系统文件,只能读里面的数据,只要你不能写,就不会对Linux系统构成威胁。
				
				有些非常重要的系统文件,甚至都不允许普通用户读,比如后面要介绍的/etc/shadow
			文件。
				
				
		(c)对于普通用户来说,一般情况下,只有读系统文件的需要
					如果你要修改里面的内容的话,必须要使用sudo,临时获取root身份,才能拥有
				root(管理员用户)才有写权限,只有这样才能修改系统文件。
	
					
		(d)用户自己的程序,需要获取系统文件数据时怎么办
					
				可以自己调用open、read等文件io函数操作这些文件,同样的一般只能读,不能写,
			如果你要写,必须以root身份运行程序,然后你才能修改文件,不过一般情况下我们
			只有读取数据的需求。
					
				为了方便操作,系统提供了专门的函数,调用这些函数可以很方便的操作文件中的数据,
			比我们自己调用open、read更方便,这些函数其实也是靠封装open、read等文件io函数来
			实现的。
					
					
						
		
(2)本章会讲些什么系统文件
			
			
		1)其实Linux的系统文件有很多,比如
			
			(a)/etc/passwd:存放用户账户信息的文件
			(b)/ext/shadow:存放密码,用户密码其实单独存放的
			(c)/etc/group:组信息
			(d)/etc/setvices:各种网络服务器的信息
			(e)/etc/protocols:各种协议的协议号
			(f)/etc/networks:网络配置信息
					....
					
				本章重点只介绍a b c这三个系统文件,其它的后面涉及到了,在具体介绍。
		
		
		2)为什么介绍/etc/passwd、/ext/shadow、/etc/group这三个系统文件
			
			(a)很有要了解
				每次登陆系统时,都需要输入用户名和密码,因此我们有必要了解下Linux是如何管理
			账户信息的。
				
				实际上其它的软件,比如人事管理系统、银行管理系统、其它OS,在管理用户的账户、
			密码时,都采用了类似的管理机制,仅站在知识面扩展的角度来说,很有必要了解下。	
						
						
			(b)完善我们第二章的my_ls程序
				my_ls在显示文件属性时,文件的属主还是ID形式。
				演示:
				
				我们需要将ID换为名字,这就必须涉及到/etc/passed、/ext/shadow、/etc/group这三个文件。

1.2 获取系统时间

(1)什么是获取系统时间
		说白了就是获取:年 月 日 时 分 秒。

		
		
(2)获取时间的API
			
			为了方便应用程序获取时间,我们可以调用相应的API。

			比如我的运行于Linux系统的C程序,需要用到系统时间时,就可以调用这些API来获取时间,
			这些API有:
		
		
		1) time :Linux的系统API
		
		2) gmtime、localtime、mktime、ctime、asctime、strftime :c库API
			库API需要系统API time的支持,后面会介绍到。
		
		
		其实所有语言的库,都有获取时间的库API,不过这些库API,同样都是基于系统API实现的。

		  gmtime、localtime
		    mktime、ctime、    ......        ......
	 	  asctime、strftime     						
					 C库时间API   C++库时间API    Java库时间API ...........
								|						 |				 	  |
								|            |			      |
								|____________|____________| ................
														 |
		                         |
		                       time(OS API)
														 |
														 |
													Linux OS

二、口令文件:/etc/passwd

2.1 什么是口令文件?

		存放用户账户信息的文件,就是口令文件。

2.2 ls 查看下 /etc/passwd

	演示
	-rw-r--r-- 1 root root 2270 Apr  5 03:31 /etc/passwd
	
	对于这个文件,只有文件所属用户root才有写权限,组员用户以及其它用户,只有读权限。

	所以当普通用户打开这个文件时,是以其它用户的身份来打开文件的,所以对应的权限只允许r,
不允许写。
	
	
	当然这个文件是没有x权限的,因为文本文件放的是文字编码,不是机器指令,不需要被cpu执行。
	
	对于普通用户而言,不需要向这个文件写入任何数据,顶多就是读取里面的数据。
	
	不过当我们调用某些命令的时候,这些个命令会去修改该文件。比如调用useradd添加新的用户,
系统执行这个命令时,系统会把新用户的账户信息,写到这个文件中保存。
	
		
文件内容:
	root:x:0:0:root:/root:/bin/bash    管理员用户的账户信息
																															 _
	daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin            		|
	bin:x:2:2:bin:/bin:/usr/sbin/nologin                          |
	sys:x:3:3:sys:/dev:/usr/sbin/nologin                          |
		........                                                    |
		........                                                     >Linux系统相关用户的账户信息
	usbmux:x:120:46:usbmux daemon,,,:/var/lib/usbmux:/bin/false   |
	  ........                                                    |
		........																			             _|
																											              
	zxf:x:1000:1000:zxf,,,:/home/zxf:/bin/bash     我自己这个普通用户的账户信息,这个普通用户是安装ubuntu时创建的               
	newUser:x:1001:1001::/home/newUser:            我使用useradd命令创建的另外一个普通用户的账户信息

2.2.1 账户所包含的信息:

			以:zxf:x:1000:1000:zxf,,,:/home/zxf:/bin/bash 为例
			
			分为7个字段,字段间使用:分隔
		
			用户名:密码:用户ID:用户所在组的组ID:注释:用户主目录的路径:shell程序的路径
				
				
		(1)用户名
				比如root、zxf、newUser
		
		(2)密码
				为了安全起见,真实的密码并不放在这里,而是放在了/etc/shadow中,这里只是使用
			一个X来代表。
				
				X表示有密码,如果没有X(字段是空的),表示这个用户没有密码。
				
				
		(3)用户ID
				root的用户ID为0,在Linux下,root管理员用户的ID都是0
				zxf的用户ID为1000
				newUser用户ID为1001
				
				用户ID都是由系统自动分配的。
				
				
		(4)组ID
				默认情况下,每个用户都有一个自己的组,组里面就自己一个组员,组长就是自己,
			自己的用户ID就是组ID。新建用户后,每个用户所在组就是自己这个组,所以你才会
			发现对于绝大多数用户来说,它的组ID也是自己的ID。其实,执行相应的命令,可以
			将我的用户加入其它用户的组,也可以其它用户也可以加入我的组,成为我的组员。
			由于有关组这个东西,在我们实际开发的过程中,我们基本用不到,因此我们这里就
			不讲如何通过命令来修改用户的所在组。
				
		(5)注释
				账户注册者的个人信息,如果信息很多的话,信息之间使用,分隔。
			
				注册者的信息有哪些呢?
				比如注册者的名字、电话、办公地址、邮箱等等。
			
				一般的人嫌麻烦,在注册账户的时,都不会填写这些内容,所以注释字段基本都是空的
			,比如我自己新注册的newUser账户,就没有注释信息。
					
					newUser:x:1001:1001::/home/newUser:
				
				
		(6)用户主目录的路径
					系统启动起来后,用户登录系统时,会用到主目录,所以这里有记录主目录的路径,
				用户登陆后,系统便会从这里得到该用户的主目录路径。
					千万不要去修改主目录的路径,修改之后很可能会导致你下一次无法登录,如
				果你好奇心重,就想改改看,那你一定要先做好ubuntu的备份。
					不仅主目录路径不能改,其它信息你也不能改。
				
					
				
		(7)shell程序的路径
				什么是shell程序?
				shell程序,是一个命令的解释程序,说白了就是解析我们从终端输入的各种命令的。
				
				在/bin下还有一个shell程序叫dash(/bin/dash),但是/etc/passwd文件中
			给的路径是/bin/bash,那么登陆后,启动的就是bash,而不是dash。
				
				因为dash和bash都是二进制的可执行程序,因此都放在了bin目录下。

2.2.2 getpwuid、getpwnam

	这两个函数的作用是,获取passwd文件中的账户数据,其实,我们也可以调用open、read等文件io
函数来读取passwd文件的数据,但是Linux系统提供了更加便捷的API,通过这些API,可以更加方便
的读取,比我们自己调用open、read来的更便捷。
			
			
	getpwuid、getpwnam这个两个函数是c库函数,这两个函数也是靠封装open、read等函数来实现的。
	
	
(1)函数原型
		#include 
		#include 
		
		struct passwd *getpwuid(uid_t uid);
		struct passwd *getpwnam(const char *name);
					
					
		1)功能
			getpwuid:使用用户ID(uid),到/etc/passwd中搜索,并获取对应账户信息。
			
			
			
			getpwnam:使用用户名(name),到/etc/passwd中搜索,并获取对应账户信息。
			
			
			调用这两个函数时,函数会开辟一个struct passwd结构体变量,然后把从文件中读到的
		账户数据,保存到结构体变量。
			
			zxf:x:1000:1000:zxf,,,:/home/zxf:/bin/bash 
			
			 struct passwd
			 {
						char   *pw_name;       /* 用户名,字符串形式 */
						char   *pw_passwd;     /* 是否有密码 */
						uid_t   pw_uid;        /* user ID ,用户ID*/
						gid_t   pw_gid;        /* group ID ,组ID*/
						char   *pw_gecos;      /* 注释 */
						char   *pw_dir;        /* 主目录路径 */
						char   *pw_shell;      /* shell程序路径 */
			 };
							

		2)返回值	
			(a)成功:返回struct passwd结构体变量的指针。
			(b)失败:返回NULL,errno被设置。

三、阴影文件:/etc/shadow

1.2.1 里面放的是什么
			放的是加密后的密码。
			
			
			
1.2.2 为什么密码要单独存放,而且还要加密
		为了让密码更安全。
	
	
(1)密码不能明文存放
			注册用户时,用户密码会被加密,而且使用的是不可逆加密算法,所谓不可逆算法,就是不能
		通过密文,反过来推算出原文。
			
			常用的不可逆算法是“摘要加密算法”,我们在讲《计算机体系结构》软件篇——计算机信息安
		全时介绍过,不了解的可以看这部分内容。
		
			为什么加密?
			如果明文存放,别人把你的密码文件偷到了,一打开,不就直接知道你的密码了吗。
		
			
			当我们登录时输入密码原文,密码加密后会被拿去和注册时登记的加密密码进行比对,如果
		相等就能登录成功。
		
		
(2)密码单独放在一个文件中(/etc/shadow),而且普通用户无法查看
			防止你猜密码。

			比如我知道你的加密算法是什么,只不过我不知道你的密码原文,怎么办呢?
			
			我就根据你的生日、街道等各种的组合猜你的密码,我再对这些猜的密码进行同样算法的加密
		,然后把加密后的密码和你注册的加密密码进行比对,如果无限制组合猜下去的话,肯定能找到
		你的密码。

			所以说最安全的方式就是,不仅要对密码加密,而且还不能让你看到我的加密后的密码。
		
		
			而/etc/passwd这个文件是可以被任何用户查看的,确实也需要被普通用户查看,所以密码
		肯定不能保存在这里面,只能把密码单独的保存在另一个文件/etc/shadow中,而且普通用户
		还无法查看这个文件。

			当然如果passwd中,该账户的密码字段为空,而不是x,表示没有密码,那么在
		/etc/shadow中,也就没有该用户的密码了。
			
			
			
			
		为什么普通用户不能查看该文件?
			/etc/shadow文件的文件权限是:
			-rw-r----- 1 root shadow 1467 Apr  7 18:47 /etc/shadow
				
				
			普通用户打开该文件时,只能以其它用对应的权限打开,但是---就没有给你任何权限。
			
			
			演示:普通打开
			
			
				不过好在,在安装ubuntu时,我的普通用户zxf和root做了关联,我可以使用sudo
			临时的变身为root用户,而root操作该文件时,对应的权限允许r,而且还允许w。
			
				当然还有一个办法,可以把我的zxf用户,加入shadow,以shadow组中组员身份操作
			shadow时,可以有r权限。
		
		
				
(3)文件中的内容						
			root:$6$5liwWndK$.o3Ixdv18/vCJhjEh10ypmexBrkL2ZMji3hzjmGAZ/W6GkHMR
			rdwMHAwLRhC3Mb9ydQCRkkALObRknCYIYo0Q1:17615:0:99999:7:::
				
				........
				
			zxf:$6$qmxD4ykF$Sa6Rag5jyietGlL/gM7Er0rosAeVrVIst0p3sX.y9Hi0Mij
			pITvl6NkKk.n76uo3RUKP9eso7Pv2URNOSslBH/:17615:0:99999:7:::
			
			newUser:$6$AuLu6Skf$QtD4niZmcGXc4nK9Vck8iPM2X3MoE3NBkkemJc
			FaKA4ZX7cGp/M/9av6vbPz7YMeSnjcYvCTSuuobn/ijTdD41:17629:0:99999:7:::

			
			
		1)分成了8个字段,相互间被“:”隔开。
			(a)字段1:用户名
			(b)字段2:加密后的密码
				
			(c)其它字段
				上次修改密码时的日期
				多少时间后,可以再次修改密码
				账户有效期
				距离到期还有多久
				等等
				
		2)$6$qmxD4ykF$Sa6Rag5jyietGlL/gM7Er0rosAeVrVIst0p3sX.y9Hi0MijpITvl6NkKk
		.n76uo3RUKP9eso7Pv2URNOSslBH/
				$6$:加密盐巴。
				
				对密码原文加密时,加密算法会把“盐巴”加进去,最终生成加密后的密码。
				密码原文是加工原料,加了“盐”就得到了菜(加密后的密码)。

				
				
				
(4)Linux也提供了的相应的API,用于获取/etc/shadow中密码信息
			
			比如struct spwd *getspnam(const char *name);
			
			根据用户名获取文件中该用户的密码信息,这个函数与的工作原理getpwuid、getpwnam
		函数是一样的。
			
			不过对于一般的开发来说,根本用涉及不到,所以我们这里就不介绍了,

四、组文件:/etc/group

4.1.1 放的是什么

我们之前说过,多个用户在一起可以组成一组,其中的某个用户担任组长,组长用户ID就是组长ID,组长用
户的名字就是整个组的名字。
		
/etc/group里面放的就是各种用户组相关的信息。

这个文件,普通用户也只能读,不能写。

4.1.2 文件内容

	root:x:0:
			
	daemon:x:1:
	bin:x:2:
	sys:x:3:

	.........
	
	
	zxf:x:1000:
	newUser:x:1001:
	

(1)分成4个字段

		1)字段1:组的名字,就是组长用户的用户名
		2)字段2:组的密码,就是组长用户的密码,x表示有密码,字段为空的话,表示没有密码
		3)字段3:组ID,就是组长用户的ID
		4)字段4:组员有哪些
		如果字段为空,表示组员就一个,就组长自己。


		我们前面介绍过,默认情况下,每个用户自己一个组,自己担任组长,在没有别的用户加入组之前
	,组员就自己一个人,自己既是将军也是兵。
	
		我们刚创建一个新文件时,你在什么用户下创建的文件,这个文件的所属用户默认就是当前用户,
	所属组就是当前用户自己的那一个组。
	
		当然我们可以使用chown来修改文件的所属组。

4.1.3 getgrgid、getgrnam函数

这两个函数同样是库函数,工作原理和getpwduid、getpwnam完全一样。
			
			
(1)函数原型
			#include 
			#include 
			
			struct group *getgrnam(const char *name);
			struct group *getgrgid(gid_t gid);
	
	
(2)函数功能
		1)getgrnam函数:利用组名搜索组文件,获取对应组的信息。
		2)getgrgid函数:利用组ID搜索组文件,获取对应组的信息。
			
		将获取的内容写到函数开辟的struct group结构体变量中,然后将指针返回给应用程序使用。
		
			zxf:x:1000:
			
			struct group
			{
					char   *gr_name;       /* 组名 */
					char   *gr_passwd;     /* 是否有组密码 */
					gid_t   gr_gid;         /* 组ID */
					char  **gr_mem;        /* 指向组成员用户名的的指针数组 */
			};								
										
										
(3)函数返回值
		调用成功,则返回指向struct group结构体变量的指针,失败则返回NULL,errno被设置。

五、其它系统文件

比如:
	/etc/services:记录了各种网络服务器提供的服务。
	/etc/protocols:记录了各种的协议。
	/etc/networks:记录网络信息

	同样也有类似get***的函数,通过这样的函数,可以获取对应系统文件的信息,后面涉及到了,再来有
针对性的介绍。
	
	有关调用函数获取系统文件信息,在实际开发中用的不多,这里介绍更多是扩展性的,希望你知道有
这么回事,对于大家来说理解即可。

六、获取系统时间

	什么是系统时间:就是年月日 时分秒,有OS时,这个时间就是系统提供的,因此成为系统时间。
		
	比如我的应用程序需要显示当前日期和时间,我就可以通过调用相应的API来获取。
	
	区分日期和时间。
	
	日期:年 月 日
	时间:时 分 秒

	准确来讲,具体的时 分 秒应该指的是时刻,两个时刻之间的差值才是时间,不过平时说习惯了,往往
把时刻也说成是时间,甚至将日期和时间都合称为时间,后面我们说到时间时,指的就是日期和时间合在
一起的情况。

6.1 Linux的计时方式

Linux系统记录的时间,是从公元1970年1月1日00:00:00开始,到现在的总秒数,每过1秒,总秒数就会+1。
		
	这个总秒数 + 1970年1月1日00:00:00这个起点时间,即可计算得到当的前时间。


	通过调用Linux系统提供系统 API——time,即可获取这个总秒数,我们可以自己去将这个总秒数转换
成年月日、时分秒,但是由于涉及到闰年闰月的问题,我们一般不会自己去转换,因为很多人连什么是
润年闰月都不清楚,自己写代码去转换不划算。


	因此Linux下的C库还提供了gmtime、localtime、mktime、ctime、asctime、strftime等C库函
数,调用这些函数就可以将time函数返回的总秒数,自动的转换为我们要的当前时间。
	
	前面说过,所有语言的库都有获取时间的库API,这些库函数都是基于系统API来实现的,如果是
windows的库,就是基于windows系统API实现的,如果是Linux的库,就是Linux的系统API实现的。
		

	  gmtime、localtime     
	    mktime、ctime、     
 	  asctime、strftime       					  	   
				 C库时间API   C++库时间API    Java库时间API ...........
							|						 |				 	  |
							|            |			      |
							|____________|____________| ................
													 |
	                         |
	                       time(OS API)
													 |
													 |
												Linux OS	

												
												
	同样不要记这些函数,理解即可,通过理解C库的时间API,了解库函数的时间API,才是重点。
	
	以后,如果在你写的c程序中用到了这些函数,查阅笔记和man手册即可。
	
	如果你写的是c++和java函数的话,那就直接调用c++和java的获取时间的库函数即可。

6.2 time

函数原型
#include 

time_t time(time_t *t);


1)功能:返回总秒数。

3)参数 t:存放总秒数的缓存的地址。

	time_t其实就是int类型,只不过被typedef重命名了。
	调用time时,我们需要定一个int变量(缓存)来存放总秒数。
	
	
	疑问:使用int的变量放总秒数,空间大小够吗?
	答:够,如果说你的总秒数,大到int型变量都放不了的话,起码需要好几百年的时间,才能累计如此
之多的总秒数,在我们有生之年你是看不到总秒数把int变量撑爆的情况,你要是能看到,估计都成大仙了。
		

2)返回值:函数调用成功返回总秒数,失败则返回(time_t)-1 ,errno被设置。

		讲到这里可以看出,获取总秒数的方式有两种。
		
		
		
	(a)通过返回值获取
			time_t tim = time(NULL);
		
			不使用参数时,参数指定为NULL。
			
			
	(b)参数
			time_t tim;
			time(&tim);

6.3 gmtime、localtime、mktime、ctime、asctime、strftime

6.3.1 系统API:time和库API:gmtime、localtime、mktime、ctime、asctime、strftime的调用关系

linux系统编程 获取系统信息_第1张图片

6.3.2 ctime

(1)函数原型
	#include 

	char *ctime(const time_t *timep);

	1)功能
		将time返回的总秒数,转为固定的格式时间,不过这个时间是国际时间,并不是本地时间(我们的本地时间是北京时间)。
		
		
	2)参数
			保存有总秒数的缓存的地址,这个总秒数,我们需要调用time来得到。
		
	3)返回值
			成功:转换后的时间字符串的指针。
			
			失败:返回NULL,errno被设置

6.3.3 gmtime、localtime、mktime

(1)gmtime
				
				1)函数原型
					#include 
					
					struct tm *gmtime(const time_t *timep);
					
					(a)功能
							将time返回的总秒数,转为国际时间的年 月 日 时 分 秒。
							
							然后开辟一个struct tm结构体变量,将年月日时分秒放到struct tm结构体变量中。
							
							struct tm 
							{
										int tm_sec;         /* 秒 */
										int tm_min;         /* 分 */
										int tm_hour;        /* 时 */
										int tm_mday;        /* 月天 */
										int tm_mon;         /* 月份 */
										int tm_year;        /* 年 */
										int tm_wday;        /* 周天 */
										int tm_yday;        /* 年天 */
										int tm_isdst;       /* 夏时令设置 */
							};
															
					(b)参数	
								存放有总秒数的缓存的地址。
								
								
								
					(c)返回值
							成功:返回struct tm结构体变量的地址,应用程序就可以使用里面存放的年 月 日 时 分 秒。
					
							失败:返回NULL,errno被设置。
							
		(2)localtime
				1)函数原型
					#include 
				
					struct tm *localtime(const time_t *timep);
				
					功能与gmtime完全一样,只不过是转为本地时间的年月日时分秒,我们的本地时间是北京时间。
				
		(3)mktime
				1)函数原型
					#include 
						
					time_t mktime(struct tm *tm);
					
					(a)功能
							将struct tm变量中的年月日时分秒,反过来转为总秒数。
									
							
					(b)返回值
							计算得到的总秒数。

6.3.4 asctime、strftime

(1)asctime
		
	1)函数原型
		#include 	
		
		char *asctime(const struct tm *tm);
				
		(a)函数功能
					
				负责将struct tm中的年月日时分秒,组合为固定格式的时间。
			
				
		(b)返回值
				转换后时间字符换的指针。
			
			
			
(2)strftime		
		
1)函数原型
	#include 	
	
	size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
					
	(a)功能
			与asctime功能一样,只不过strftime能够组合为我们自己指定的时间格式。
			
			为了组合为我们自定义的时间格式,我们需要为函数其指定格式。
			
		
	(b)返回值
			返回转换后时间字符串的字符个数。
			
			
	(c)参数
		· s:缓存地址,这个缓存用于存放转换后的字符串。
		
		· max:缓存的大小
		
		· tm:放有年月日时分秒的结构体变量的地址。
		
		· format:自定义时间格式
		与printf("%d %s", a, buf);指定打印格式的操作方式是一样的。
		
		格式怎么用?
			比如:
			strftime(strtim_buf, sizeof(strtim_buf), "%Y:%m:%d %H:%M:%S\n", tm);
			
			%Y:%m:%d %H:%M:%S指定的时间格式,是中国人惯用的格式 ———— 年:月:日 时:分:秒。

				格式表如下:
					%a:缩写周日名							TUE
					%A:全周日名								Tuesday
					%b:缩写月名								Jan
					%B:月全名									January
					%c:固定格式的日期和时间		Tue Jan 14 19:40:30	1992
					%d:月日										26
					%H:24小时制								23
					%I:小时(上下午12小时制)	11
					%j:年日										089
					%m:月份										08
					%M:分											55
					%p:AM/PM(上下午指示)			PM
					%s:秒											30					
					%w:(周天到周6用0~6 表示)	0
					%x:固定格式日期						01/14/92
					%X:固定格式时间						19:40:30
					%y:不带公园的年						18
					%Y:带公元的年							2018
					%z:时区名									MST、DST、WET、......
									
					有关这个表,不要记,你也记不住,理解了,用到时查man手册即可。

你可能感兴趣的:(linux系统编程,linux,服务器)