天天看點

擷取linux詳細資訊,通過程式設計擷取Linux檔案系統使用的詳細資訊

去年的作業系統課程設計,我做了一個基于linux到任務管理器。大部分需要到系統資訊都是從linux下

的一個僞檔案系統/proc中讀出的。大家都知道,此檔案系統隻存在記憶體當中,而不占用外存空間。它以檔案系統的方式為通路系統核心資料的操作提供接口。使用者和應用程式可以通過proc得到系統的資訊,并可以改變核心的某些參數。比如說我想看一下系統cpu的資訊,由于其資訊存于/proc/cpuinfo中,是以我們在終端用輸入如下指令:cat /proc/cpuinfo即可檢視要檢視到資訊,如果要使用其中到某項資訊則通過檔案操作讀出即可(當然要有一些處理)。其他像記憶體、程序等各項資訊都能按照這種操作得到。可唯獨在擷取檔案系統使用資訊時遇到了問題,先來看一下我們這個項目中要做出的一個類似頁面:

擷取linux詳細資訊,通過程式設計擷取Linux檔案系統使用的詳細資訊

圖中所顯示的裝置、目錄等資訊既是我們希望從系統中得到到資訊,可/proc目錄中記錄檔案資訊的檔案partitions記錄的資訊于我們想要得到到資訊相差太遠,

[email protected]:~$ cat /proc/partitions

major minor  #blocks  name

8        0  244198584 sda

8        1   38427448 sda1

8        2          1 sda2

8        5   63898506 sda5

8        6   61440561 sda6

8        7   10241406 sda7

8        8   46138648 sda8

8        9   21430678 sda9

8       10     650601 sda10

8       11    1967931 sda11

看到了吧,裡面的資訊隻有這幾項,顯然不行。後來,我又以為所需到資訊可以從/dev下的檔案中查找,可那裡面到檔案都是不可讀的,我不停的在/proc下分析每個檔案内容,可都沒有我想要到内容,這個過程非常郁悶。可問題昨天晚上還是解決了,我通過系統調用實作的,在此,我将代碼公開,一是讓大家看一下,再一個就是如果哪位仁兄有能在檔案中直接讀出的方法,希望能告知一二,在此不勝感激。

下面這個程式是我和同學不斷讨論後設計出的一個非常巧妙的解決方案,具體代碼如下:

//讀出系統檔案系統的使用情況,并列印輸出

#include#include#include#include #include typedef struct {

char device[ 256 ];    //裝置名稱

char mntpnt[ 256 ];    //目錄

char type[256];    //類型

long blocks;        //總容量(機關為:MB)

long bfree;        //空閑容量(機關為:MB)

long bused;          //已用容量(機關為:MB)

long available_disk;    //可用容量

int bused_percent;    //使用百分比(使用率乘以100)

} DiskInfo;

//所使用到到兩個系統調用結構體

//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; 

//           };

//  struct mntent {

//               char *mnt_fsname;  

//               char *mnt_dir;     

//               char *mnt_type;    

//               char *mnt_opts;    

//               int   mnt_freq;    

//               int   mnt_passno;  

//           };

int main()

{

DiskInfo *disk_info;

struct statfs fs_info;

struct mntent *mnt_info;

FILE *fh;

float percent;        //用于儲存設備使用百分比

long total_free=0;    //用于存儲linux下尚餘磁盤空間

if ( ( fh = setmntent( "/etc/mtab", "r" ) ) == NULL )

{

printf( "Cannot open \'/etc/mtab\'!\n" );

return -1;

}

while ( ( mnt_info = getmntent( fh ) ) != NULL )

{

if ( statfs( mnt_info->mnt_dir, &fs_info ) < 0 )

{

continue;

}

if ( ( disk_info = (DiskInfo *)malloc( sizeof( DiskInfo ) ) )   == NULL )

{

continue;

}

//通過判斷找到要找的格式

if ( strcmp( mnt_info->mnt_type, "proc" ) &&

strcmp( mnt_info->mnt_type, "devfs" ) &&

strcmp( mnt_info->mnt_type, "usbfs" ) &&

strcmp( mnt_info->mnt_type, "sysfs" ) &&

strcmp( mnt_info->mnt_type, "tmpfs" ) &&

strcmp( mnt_info->mnt_type, "devpts" )&&

strcmp( mnt_info->mnt_type, "fusectl" ) &&

strcmp( mnt_info->mnt_type, "debugfs" )&&

strcmp( mnt_info->mnt_type, "binfmt_misc" )&&

strcmp( mnt_info->mnt_type, "fuse.gvfs-fuse-daemon" )&&

strcmp( mnt_info->mnt_type, "securityfs" )

)

{

if ( fs_info.f_blocks != 0 )

{

percent = ( ( (float)fs_info.f_blocks - (float)fs_info.f_bfree ) * 100.0/

(float)fs_info.f_blocks );

}

else

{

percent = 0;

}

}

else

{

continue;

}

//将系統中的各項資訊存于結構體相對應到變量中

strcpy(disk_info->type,mnt_info->mnt_type);

strcpy(disk_info->device,mnt_info->mnt_fsname);

strcpy(disk_info->mntpnt,mnt_info->mnt_dir);

long block_size=fs_info.f_bsize/1024;

disk_info->blocks = fs_info.f_blocks*block_size/1024;

disk_info->bfree = fs_info.f_bfree*block_size/1024;

disk_info->available_disk = fs_info.f_bavail*block_size/1024;

disk_info->bused = (fs_info.f_blocks - fs_info.f_bfree)*block_size/1024;

disk_info->bused_percent = (int)percent;

printf("塊大小:%dB\n",fs_info.f_bsize); //經測試每塊大小不一定一樣,根據分區格式确定的

//将各項資訊列印輸出

printf("裝置号:%s  目錄:%s  檔案類型:%s  總數:%ldMB  空閑:%ldMB  可用:%ldMB  已用:%ldMB  已用百分比:%d\n\n\n",

disk_info->device,disk_info->mntpnt,disk_info->type,disk_info->blocks,disk_info->bfree,

disk_info->available_disk,disk_info->bused,disk_info->bused_percent);

if((strcmp(disk_info->mntpnt,"/")==0)||(strcmp(disk_info->mntpnt,"/boot")==0))

{

total_free+=disk_info->available_disk;

}

};

printf("\nlinux下總的磁盤可用空間:%ldMB\n",total_free);

printf(" \nSuccess !\n");

return 0;

運作過程:

[email protected]:~/桌面/gcc$ gcc -c file2.c -o file2.o

[email protected]:~/桌面/gcc$ gcc file2.o -o file2

[email protected]:~/桌面/gcc$ ./file2

塊大小:4096B

裝置号:/dev/sda9  目錄:/  檔案類型:ext4  總數:20599MB  空閑:17203MB  可用:16157MB  已用:3396MB  已用百分比:16

塊大小:4096B

裝置号:/dev/sda10  目錄:/boot  檔案類型:ext4  總數:625MB  空閑:579MB  可用:547MB  已用:45MB  已用百分比:7

塊大小:4096B

裝置号:/dev/sda1  目錄:/media/SYSTEM  檔案類型:fuseblk  總數:37526MB  空閑:21136MB  可用:21136MB  已用:16390MB  已用百分比:43

塊大小:32768B

裝置号:/dev/sda5  目錄:/media/SOURCE  檔案類型:vfat  總數:62385MB  空閑:35201MB  可用:35201MB  已用:27184MB  已用百分比:43

塊大小:4096B

裝置号:/dev/sda6  目錄:/media/Study  檔案類型:fuseblk  總數:60000MB  空閑:14746MB  可用:14746MB  已用:45254MB  已用百分比:75

塊大小:4096B

裝置号:/dev/sda7  目錄:/media/music  檔案類型:fuseblk  總數:10001MB  空閑:1891MB  可用:1891MB  已用:8109MB  已用百分比:81

linux下總的磁盤可用空間:16704MB

Success !