一、前言php
在嵌入式设备中,硬盘空间很是有限,在涉及到常常写日志的进程时候,须要考虑日志的大小和删除,否则很快就硬盘写满,致使日志程序崩溃。为了捕获硬盘写满的异常场景,咱们须要在写日志过程当中判断硬盘空间的使用状况,根据硬盘的使用状况,就能够判断是否写满了。若是将要写满了,就给出警告。这样就能够避免程序崩溃。首先看一下linux获取硬盘和目录大小的命令,最后总结一下statfs结构和函数。html
二、df命令node
Linux下能够用df命令获取硬盘的使用状况,经过man能够获取df命令的详细状况。df命令常常用的参数为:mysql
a:显示所有的档案系统和各分割区的磁盘使用情形
i:显示i -nodes的使用量
k:大小用k来表示 (默认值)
t:显示某一个档案系统的全部分割区磁盘使用量
x:显示不是某一个档案系统的全部分割区磁盘使用量
T:显示每一个分割区所属的档案系统名称
经常使用命令:df -hi linux
举例截图以下所示sql
:数据库
三、du命令数组
du命令用来查询档案或目录的磁盘使用空间,经过man获取du命令的详细介绍。经常使用的命令参数以下:
a:显示所有目录和其次目录下的每一个档案所占的磁盘空间
b:大小用bytes来表示 (默认值为k bytes)
c:最后再加上总计 (默认值)
s:只显示各档案大小的总合 (summarize)
x:只计算同属同一个档案系统的档案
L:计算全部的档案大小
经常使用命令:du -ahsession
举例操做以下图所示:less
简单总结一下:df与du的区别,du查看目录大小,df查看磁盘使用状况。
关于df和du详细介绍能够参考:
http://www.douban.com/group/topic/2833196
/http://blog.csdn.net/kmesg/article/details/6570800
df 和 du 命令详解
df命令详细用法
a:显示所有的档案系统和各分割区的磁盘使用情形
i:显示i -nodes的使用量
k:大小用k来表示 (默认值)
t:显示某一个档案系统的全部分割区磁盘使用量
x:显示不是某一个档案系统的全部分割区磁盘使用量
T:显示每一个分割区所属的档案系统名称
经常使用命令:df -hi
操做详解
引用
指令 df 能够显示目前全部档案系统的最大可用空间及使用情形,请看下列这个例子:
# df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/ad0s1a 1.9G 389M 1.4G 21% /
devfs 1.0K 1.0K 0B 100% /dev
/dev/ad0s1d 989M 54K 910M 0% /tmp
/dev/ad0s1f 4.8G 3.8G 657M 86% /usr
/dev/ad0s1e 1.9G 149M 1.6G 8% /var
/dev/ad0s1g 26G 890K 24G 0% /volume2
/dev/da0s1d 325G 261G 38G 87% /volume1
咱们加了参数 -h 表示使用「Human-readable」的输出,也就是在档案系统大小使用 GB、MB 等易读的格式。
上面的指令输出的第一个字段及最后一个字段分别是档案系统及其挂入点。咱们能够看到 /dev/ad0s1a 这个分割区被挂在根目录下。咱们在上一小节提到过 ad 所表明的是 IDE 的硬盘,而 s1 表示第一个主要扇区。我另外有一个 SCSI 硬盘,它的代号是 da,它的容量很大,主要用来存放数据。devfs 是一个特别的档案系统,该档案系统并不是真的磁盘,而是 FreeBSD 用来管理系统硬件装置的虚拟档案系统。
接下来的四个字段 Size、Used、Avail、及 Capacity 分别是该分割区的容量、已使用的大小、剩下的大小、及使用的百分比。当硬盘容量已满时,您可能会看到已使用的百分比超过 100%,由于 FreeBSD 会留一些空间给 root,让 root 在档案系统满时,仍是能够写东西到该档案系统中,以进行管理。
另外,咱们还可使用参数 -i 来查看目前档案系统 inode 的使用情形。有的时候虽然档案系统还有空间,但若没有足够的 inode 来存放档案的信息,同样会不能增长新的档案。
# df -ih
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on
/dev/ad0s1a 1.9G 389M 1.4G 21% 20495 262127 7% /
devfs 1.0K 1.0K 0B 100% 0 0 100% /dev
/dev/ad0s1d 989M 62K 910M 0% 24 141286 0% /tmp
/dev/ad0s1f 4.8G 3.8G 657M 86% 311439 348015 47% /usr
/dev/ad0s1e 1.9G 149M 1.6G 8% 1758 280864 1% /var
/dev/ad0s1g 26G 890K 24G 0% 12 3532786 0% /volume2
/dev/da0s1d 325G 261G 38G 87% 707277 43311409 2% /volume1
咱们能够看到根目录的已经用掉的 inode 数量为 20495,还有 262127 的可用 inode。
小提示
还记得什么是 inode 吗?所谓的 inode 是用来存放档案及目录的基本信息 (metadata),包含时间、档名、使用者及群组等。在分割扇区时,系统会先作出一堆 inode 以供之后使用,inode 的数量关系着系统中能够创建的档案及目录总数。若是要存的档案大部分都很小,则一样大小的硬盘中会有较多的档案,也就是说须要较多的 inode 来挂档案及目录。
du:查询档案或目录的磁盘使用空间
a:显示所有目录和其次目录下的每一个档案所占的磁盘空间
b:大小用bytes来表示 (默认值为k bytes)
c:最后再加上总计 (默认值)
s:只显示各档案大小的总合 (summarize)
x:只计算同属同一个档案系统的档案
L:计算全部的档案大小
经常使用命令:du -a
操做详解
引用
指令 du 能以指定的目录下的子目录为单位,显示每一个目录内全部档案所占用的磁盘空间大小。例如:
# du -h /etc
104K /etc/defaults
6.0K /etc/X11
8.0K /etc/bluetooth
4.0K /etc/gnats
52K /etc/isdn
388K /etc/mail
68K /etc/mtree
2.0K /etc/ntp
38K /etc/pam.d
44K /etc/periodic/daily
6.0K /etc/periodic/monthly
42K /etc/periodic/security
16K /etc/periodic/weekly
110K /etc/periodic
6.0K /etc/ppp
318K /etc/rc.d
2.0K /etc/skel
130K /etc/ssh
10K /etc/ssl
1.7M /etc
咱们目样使用 -h 参数来显示 human-readable 的格式。在应用时,咱们可使用 du 这个指令来查看哪一个目录占用最多的空间。不过,du 的输出结果一般很长,咱们能够加上 -s 参数来省略指定目录下的子目录,而只显示该目录的总合便可:
# du -sh /etc
1.7M /etc
在查看目录的使用情形时,咱们能够将输出结果导到 sort 指令进行排序,以了解哪一个档案用了最多的空间:
# du /etc | sort -nr | more
1746 /etc
388 /etc/mail
318 /etc/rc.d
130 /etc/ssh
110 /etc/periodic
104 /etc/defaults
68 /etc/mtree
52 /etc/isdn
44 /etc/periodic/daily
42 /etc/periodic/security
38 /etc/pam.d
16 /etc/periodic/weekly
10 /etc/ssl
8 /etc/bluetooth
6 /etc/ppp
6 /etc/periodic/monthly
6 /etc/X11
4 /etc/gnats
2 /etc/skel
2 /etc/ntp
sort 的参数 -nr 表示要以数字排序法进行反向排序,由于咱们要对目录大小作排序,因此不可使用 human-readable 的大小输出,否则目录大小中会有 K、M 等字样,会形成排序不正确。
linux的du和df命令
今天也有同窗问我Linux下查看目录大小的命令,如今也将前阵子学习到du/df两个命令总结一下吧。
前阵子测试工做中有遇到过因为磁盘空间满致使程序没法执行到状况,因此使用了df和du两个命令。
du查看目录大小,df查看磁盘使用状况。
我常使用的命令(必要时,sudo使用root权限),
1.查看某个目录的大小:du -hs /home/master/documents
查看目录下全部目录的大小并按大小降序排列:sudo du -sm /etc/* | sort -nr | less
2.查看磁盘使用状况(文件系统的使用状况):sudo df -h
df --block-size=GB
-h是使输出结果更易于人类阅读;du -s只展现目录的使用总量(不分别展现各个子目录状况),-m是以MB为单位展现目录的大小(固然-k/-g就是KB/GB了)。
更多信息,仍是man du 和 man df 来得到吧。
du - estimate file space usage
Summarize disk usage of each FILE, recursively for directories.
df - report file system disk space usage
Show information about the file system on which each FILE resides, or all file systems by default.
df displays the amount of disk space available on the file system containing each file nameargument. If no file name is given, the space available on all currently mounted file systems is shown.
du
du的英文为:disk usage,含义是磁盘空间使用状况,功能是逐级进入指定目录的每个子目录并显示该目录占用文件系统数据块的状况,若是没有指定目录,则对当前的目录进行统计。
du的命令各个选项含义以下:
a:显示所有目录和其次目录下的每一个档案所占的磁盘空间
s:只显示各档案大小的总合
b:大小用bytes来表示
x:跳过在不一样文件系统上的目录不予统计
a:递归地显示指定目录中各文件及子孙目录中各文件占用的数据块数
...
使用du进行查看
root@tech163:/home/htmlfile# du
16 ./test
60 ./bbb
84 .
其中第一列是以块为单位计的磁盘空间容量,第二列列出目录中使用这些空间的目录名称
1)查看当前目录包含子目录的大小
root@tech163:/home/htmlfile# du -sm .
1 .
其中的du -sm . 的“.”是表明当前目录。
2)查看当前目录以及子目录的大小
root@tech163:/home/htmlfile# du -h
16K ./test
60K ./bbb
84K .
其中 -h 表示使用K,M,G的人性化形式显示。
3)看到当前目录下的bbb目录大小,但不想查看其余目录以及子目录
root@tech163:/home/htmlfile# du -ch bbb | tail -n 1
60K total
使用了管道包含了du和tail两个命令,-c表示最后计算出所列目录的大小之和。
4)列出当前目录下全部目录和文件的大小
root@tech163:/home/htmlfile# du -ah bbb
4.0K bbb/mysql.php
4.0K bbb/index.htm
4.0K bbb/p.php
28K bbb/memcache.php
12K bbb/.session.php.swp
4.0K bbb/hello.html
60K bbb
其中-a表示包含目录和文件
5)不换行列出目录以及子目录大小的信息
root@tech163:/home/htmlfile# du -0h
16K ./test60K ./bbb84K .root@tech163:/home/htmlfile#
其中 -0 表示列出一条信息后不换行,接着输出第二条信息。
df
于du不一样的是,du是面向文件的命令,只计算被文件占用的空间。不计算文件系统metadata 占用的空间。df则是基于文件系统整体来计算,经过文件系统中未分配空间来肯定系统中已经分配空间的大小。df命令能够获取硬盘占用了多少空间,还剩下多少空间,它也能够显示全部文件系统对i节点和磁盘块的使用状况。
df命令各个选择的含义以下:
a:显示所有的档案系统和各分割区的磁盘使用情形
i:显示i -nodes的使用量
k:大小用k来表示 (默认值)
t:显示某一个档案系统的全部分割区磁盘使用量
x:显示不是某一个档案系统的全部分割区磁盘使用量
T:显示每一个分割区所属的档案系统名称
....
使用df进行查看
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/cciss/c0d0p1 2068156 611572 1351528 32% /
tmpfs 1038080 4 1038076 1% /lib/init/rw
udev 10240 64 10176 1% /dev
tmpfs 1038080 4 1038076 1% /dev/shm
/dev/cciss/c0d0p9 130700120 44034236 86665884 34% /home
/dev/cciss/c0d0p7 2068156 68932 1999224 4% /tmp
/dev/cciss/c0d0p8 4132372 1760620 2161840 45% /usr
/dev/cciss/c0d0p6 2068156 330104 1632996 17% /var
第一行是文件系统对应的硬盘分区
第二行是分区包含的数据块的数据(1数据库为1024字节)
第三四行是已用和未用的数据块数组
第五行是普通用户空间使用的百分比
第六行是文件系统的安装点
其中第三四行已用和未用数据块相加并不等于第二行总数据块,这是由于分区留了少许空间提供给
系统管理员使用。
1)
chenyz@gzhouse:~$ df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/cciss/c0d0p1 2.0G 598M 1.3G 32% /
tmpfs 1014M 4.0K 1014M 1% /lib/init/rw
udev 10M 64K 10M 1% /dev
tmpfs 1014M 4.0K 1014M 1% /dev/shm
/dev/cciss/c0d0p9 125G 42G 83G 34% /home
/dev/cciss/c0d0p7 2.0G 68M 2.0G 4% /tmp
/dev/cciss/c0d0p8 4.0G 1.7G 2.1G 45% /usr
/dev/cciss/c0d0p6 2.0G 333M 1.6G 18% /var
其中 -h 表示使用K,M,G的人性化形式显示。
2)
chenyz@gzhouse:~$ df -ia
文件系统 Inode (I)已用 (I)可用 (I)已用% 挂载点
/dev/cciss/c0d0p1 262752 60150 202602 23% /
tmpfs 224142 10 224132 1% /lib/init/rw
proc 0 0 0 - /proc
sysfs 0 0 0 - /sys
procbususb 0 0 0 - /proc/bus/usb
udev 224142 770 223372 1% /dev
tmpfs 224142 3 224139 1% /dev/shm
devpts 0 0 0 - /dev/pts
/dev/cciss/c0d0p9 130763968 1972907 128791061 2% /home
/dev/cciss/c0d0p7 262752 54 262698 1% /tmp
/dev/cciss/c0d0p8 524832 35743 489089 7% /usr
/dev/cciss/c0d0p6 262752 4896 257856 2% /var
所谓的 inode 是用来存放档案及目录的基本信息,包含时间、档名、使用者及群组等。在分割扇区时,系统会先作出一堆 inode 以供之后使用,inode 的数量关系着系统中能够创建的档案及目录总数。若是要存的档案大部分都很小,则一样大小的硬盘中会有较多的档案,也就是说须要较多的 inode 来挂档案及目录
四、statfs结构及函数
以前在看APUE时候,在第四章文件和目录中,讲到了获取文件信息的stat结构,经过stat结构能够获文件的大小,建立时间,修改时间,用户id,组id等等。关于stat结构请参考:http://linux.about.com/library/cmd/blcmdl2_stat.htm。man上stat结构及操做函数以下图所示:
今天主要总结学习一下获取硬盘信息的statfs结构,经过statfs结构的信息计算出路径所在的磁盘使用状况。
man上关于statfs介绍以下所示:
statfs结构的中文意思以下所示:
1 struct statfs 2 { 3 long f_type; /* 文件系统类型*/ 4 long f_bsize; /* 通过优化的传输块大小*/ 5 long f_blocks; /* 文件系统数据块总数*/ 6 long f_bfree; /* 可用块数*/ 7 long f_bavail; /* 非超级用户可获取的块数*/ 8 long f_files; /* 文件结点总数*/ 9 long f_ffree; /* 可用文件结点数*/ 10 fsid_t f_fsid; /* 文件系统标识*/ 11 long f_namelen; /* 文件名的最大长度*/ 12 };
statfs结构中可用空间块数有两种f_bfree和 f_bavail,前者是硬盘全部剩余空间,后者为非root用户剩余空间,ext3文件系统给root用户分有5%的独享空间,因此这里是不一样的地方。这里要强调的是每块的大小通常是4K。所以,要实现与df结果一致的就得在得到块数上乘以4,这样已用、可用、总块数就能够实现。
测试程序以下所示:
1 #include <stdio.h> 2 #include <sys/statfs.h> 3 #include <sys/vfs.h> 4 #include <errno.h> 5 6 int main(int argc, char *argv[]) 7 { 8 struct statfs disk_info; 9 char *path = "/home/"; 10 int ret = 0; 11 if (argc == 2) 12 { 13 path = argv[1]; 14 } 15 if (ret == statfs(path, &disk_info) == -1) 16 { 17 fprintf(stderr, "Failed to get file disk infomation,\ 18 errno:%u, reason:%s\n", errno, strerror(errno)); 19 return -1; 20 } 21 long long total_size = disk_info.f_blocks * disk_info.f_bsize; 22 long long available_size = disk_info.f_bavail * disk_info.f_bsize; 23 long long free_size = disk_info.f_bfree * disk_info.f_bsize; 24 //输出每一个块的长度,linux下内存块为4KB 25 printf("block size: %ld bytes\n", disk_info.f_bsize); 26 //输出块个数 27 printf("total data blocks: %ld \n", disk_info.f_blocks); 28 //输出path所在磁盘的大小 29 printf("total file disk size: %d MB\n",total_size >> 20); 30 //输出非root用户能够用的磁盘空间大小 31 printf("avaiable size: %d MB\n",available_size >> 20); 32 //输出硬盘的全部剩余空间 33 printf("free size: %d MB\n",free_size >> 20); 34 //输出磁盘上文件节点个数 35 printf("total file nodes: %ld\n", disk_info.f_files); 36 //输出可用文件节点个数 37 printf("free file nodes: %ld\n", disk_info.f_ffree); 38 //输出文件名最大长度 39 printf("maxinum length of file name: %ld\n", disk_info.f_namelen); 40 return 0; 41 }
测试结果以下所示:
五、参考网址:
http://www.cnblogs.com/hnrainll/archive/2011/05/11/2043361.html
http://blog.sina.com.cn/s/blog_6385c7310100jk1f.html
linux stat函数讲解
stat函数讲解
表头文件: #include <sys/stat.h>
#include <unistd.h>
定义函数: int stat(const char *file_name, struct stat *buf);
函数说明: 经过文件名filename获取文件信息,并保存在buf所指的结构体stat中
返回值: 执行成功则返回0,失败返回-1,错误代码存于errno
错误代码:
ENOENT 参数file_name指定的文件不存在
ENOTDIR 路径中的目录存在但却非真正的目录
ELOOP 欲打开的文件有过多符号链接问题,上限为16符号链接
EFAULT 参数buf为无效指针,指向没法存在的内存空间
EACCESS 存取文件时被拒绝
ENOMEM 核心内存不足
ENAMETOOLONG 参数file_name的路径名称太长
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
int main() {
struct stat buf;
stat("/etc/hosts", &buf);
printf("/etc/hosts file size = %d\n", buf.st_size);
}
-----------------------------------------------------
struct stat {
dev_t st_dev; //文件的设备编号
ino_t st_ino; //节点
mode_t st_mode; //文件的类型和存取的权限
nlink_t st_nlink; //连到该文件的硬链接数目,刚创建的文件值为1
uid_t st_uid; //用户ID
gid_t st_gid; //组ID
dev_t st_rdev; //(设备类型)若此文件为设备文件,则为其设备编号
off_t st_size; //文件字节数(文件大小)
unsigned long st_blksize; //块大小(文件系统的I/O 缓冲区大小)
unsigned long st_blocks; //块数
time_t st_atime; //最后一次访问时间
time_t st_mtime; //最后一次修改时间
time_t st_ctime; //最后一次改变时间(指属性)
};
先前所描述的st_mode 则定义了下列数种状况:
S_IFMT 0170000 文件类型的位遮罩
S_IFSOCK 0140000 scoket
S_IFLNK 0120000 符号链接
S_IFREG 0100000 通常文件
S_IFBLK 0060000 区块装置
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符装置
S_IFIFO 0010000 先进先出
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件全部者具可读取权限
S_IWUSR(S_IWRITE)00200 文件全部者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件全部者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其余用户具可读取权限
S_IWOTH 00002 其余用户具可写入权限
S_IXOTH 00001 其余用户具可执行权限
上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode) 判断是否为符号链接
S_ISREG (st_mode) 是否为通常文件
S_ISDIR (st_mode) 是否为目录
S_ISCHR (st_mode) 是否为字符装置文件
S_ISBLK (s3e) 是否为先进先出
S_ISSOCK (st_mode) 是否为socket
若一目录具备sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件全部者、此目录全部者或root来删除或更名。
-----------------------------------------------------
struct statfs {
long f_type; //文件系统类型
long f_bsize; //块大小
long f_blocks; //块多少
long f_bfree; //空闲的块
long f_bavail; //可用块
long f_files; //总文件节点
long f_ffree; //空闲文件节点
fsid_t f_fsid; //文件系统id
long f_namelen; //文件名的最大长度
long f_spare[6]; //spare for later
};
stat、fstat和lstat函数(UNIX)
#include<sys/types.h>
#include<sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);
提供文件名字,获取文件对应属性。感受通常是文件没有打开的时候这样操做。
int fstat(int filedes, struct stat *buf);
经过文件描述符获取文件对应的属性。文件打开后这样操做
int lstat(const char *restrict pathname, struct stat *restrict buf);
链接文件
三个函数的返回:若成功则为0,若出错则为-1
给定一个pathname,stat函数返回一个与此命名文件有关的信息结构,fstat函数得到已在描述符filedes上打开的文件的有关信息。lstat函数相似于stat,可是当命名的文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用的文件的信息。
第二个参数是个指针,它指向一个咱们应提供的结构。这些函数填写由buf指向的结构。该结构的实际定义可能随实现而有所不一样,但其基本形式是:
struct stat{
mode_t st_mode; /*file tpye &mode (permissions)*/
ino_t st_ino; /*i=node number (serial number)*/
dev_t st_rdev; /*device number for special files*/
nlink_t st_nlink; /*number of links*/
uid_t st_uid; /*user id of owner*/
gid_t st_gid; /*group ID of owner*/
off_t st_size; /*size in bytes for regular files*/
time_t st_atime; /*time of last access*/
time_t st_mtime; /*time of last modification*/
time_t st_ctime; /*time of last file status change*/
long st_blksize; /*best I/O block size */
long st_blocks; /*number of 512-byte blocks allocated*/
};
注意,除最后两个之外,其余各成员都为基本系统数据类型。咱们将说明此结构的每一个成员以了解文件属性。
使用stat函数最多的多是ls-l命令,用其能够得到有关一个文件的全部信息。
1 函数都是获取文件(普通文件,目录,管道,socket,字符,块()的属性。
函数原型
#include <sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);
提供文件名字,获取文件对应属性。
int fstat(int filedes, struct stat *buf);
经过文件描述符获取文件对应的属性。
int lstat(const char *restrict pathname, struct stat *restrict buf);
链接文件描述命,获取文件属性。
2 文件对应的属性
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //inode节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的链接数
uid_t st_uid; //文件全部者
gid_t st_gid; //文件全部者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //伟建内容对应的块数量
};
能够经过上面提供的函数,返回一个结构体,保存着文件的信息。
statfs得到硬盘使用状况
先说statfs结构:
#include <sys/vfs.h>
int statfs(const char *path, struct statfs *buf);
int fstatfs(int fd, struct statfs *buf);
参数:
path: 位于须要查询信息的文件系统的文件路径名。
fd: 位于须要查询信息的文件系统的文件描述词。
buf:如下结构体的指针变量,用于储存文件系统相关的信息
struct statfs {
long f_type;
long f_bsize;
long f_blocks;
long f_bfree;
long f_bavail;
long f_files;
long f_ffree;
fsid_t f_fsid;
long f_namelen;
};
statfs结构中可用空间块数有两种f_bfree和 f_bavail,前者是硬盘全部剩余空间,后者为非root用户剩余空间,ext3文件系统给root用户分有5%的独享空间,因此这里是不一样的地方。这里要强调的是每块的大小通常是4K。所以,要实现与df结果一致的就得在得到块数上乘以4,这样已用、可用、总块数就能够实现。若是还要实现百分比一致,那么要注意的是,df命令得到是整数百分比,没有小数,这里使用的进一法,而不是四舍五入法。因此在程序里直接+1取整。
下面是实现的一个例子:(home目录为一个独立分区)
#include <stdio.h>#include <sys/vfs.h>
int main()
{
struct statfs sfs;
int i = statfs("/home", &sfs);
int percent = (sfs.f_blocks - sfs.f_bfree ) * 100 / (sfs.f_blocks - sfs.f_bfree + sfs.f_bavail) + 1;
printf("/dev/sda11 %ld %ld %ld %d%% /home\n",
4*sfs. f_blocks, 4*(sfs.f_blocks - sfs.f_bfree), 4*sfs.f_bavail, percent);
system("df /home ");
return 0;
}
执行结果:
leave@LEAVE:~/test$ gcc -o df df.c leave@LEAVE:~/test$ ./df /dev/sda11 42773008 540356 40059864 2% /home 文件系统 1K-块 已用 可用 已用% 挂载点 /dev/sda11 42773008 540356 40059864 2% /home leave@LEAVE:~/test$