前言:linux 中的 /proc 文件系統(tǒng),由一組目錄和文件組成,掛載 (mount) 與 /proc 目錄下。
/proc 文件系統(tǒng)是一種虛擬文件系統(tǒng),以文件系統(tǒng)目錄和文件形式,提供一個(gè)指向內(nèi)核數(shù)據(jù)結(jié)構(gòu)的接口。 這為查看和改變各種系統(tǒng)屬性開啟了方便之門。 此外,還能通過一組以 /proc/PID 形式命名的目錄 (PID 是進(jìn)程的 ID) 查看系統(tǒng)匯總運(yùn)行各進(jìn)程的相關(guān)信息。
通常,/proc 目錄下的文件內(nèi)容都采取可讀的文本形式,shell 腳本也能對(duì)其進(jìn)行解析。 程序可以打開,讀取和寫入 /proc 目錄下的既定文件。 大多數(shù)情況下,只有特權(quán)進(jìn)程才能修改 /proc 目錄下的文件內(nèi)容。
proc 文件系統(tǒng)初步
/proc 文件系統(tǒng)
/proc 文件系統(tǒng)是一種特殊的,由軟件創(chuàng)建的文件系統(tǒng),內(nèi)核使用它向外界到處信息。 /proc 下面的每個(gè)文件都綁定一個(gè)內(nèi)核文件,用戶讀取其中的文件時(shí),該函數(shù)動(dòng)態(tài)的生成文件的“內(nèi)容”。
由于 `/proc` 文件系統(tǒng)已經(jīng)被添加了大量的信息。因此,最好的辦法是使用 `sysfs` 而不是 `/proc` 文件系統(tǒng)想歪導(dǎo)出信息。
`/proc` 文件不僅可以用于讀數(shù)據(jù),也可以用于寫數(shù)據(jù),不過寫數(shù)據(jù)比較麻煩一些,這里只描述數(shù)據(jù)的用法。 寫數(shù)據(jù)的方法可以在看完讀數(shù)據(jù)的過程后參考 kernel 源碼
創(chuàng)建 /proc 文件的函數(shù)
前面說了 /proc 下的文件都是在訪問實(shí)時(shí)生成文件內(nèi)容的,那么為了創(chuàng)建 /proc 下的一個(gè)只讀的文件,我們必須實(shí)現(xiàn)一個(gè)函數(shù)用于在讀取文件時(shí)生成數(shù)據(jù),萬幸,該函數(shù)接口設(shè)計(jì)好了,我們只要按照函數(shù)接口實(shí)現(xiàn)自己需要的功能就可以了。 函數(shù)原型如下:
int (*read_proc)(char *page,char **start,off_t offset,int count,int *eof,void *data);
參數(shù)說明:
```參數(shù)名
說明
page
用來寫入數(shù)據(jù)的緩沖區(qū); 也就是說從 /proc 文件中獨(dú)到的數(shù)據(jù)都寫入到 page 指向的緩沖區(qū)中
start
用于指定事跡的數(shù)據(jù)寫入到 page 指向的內(nèi)存也的具體的那個(gè)位置
offset
和 read 函數(shù)中的參數(shù)意義相同
count
和 read 函數(shù)中的參數(shù)意義相同
eof
當(dāng)沒有數(shù)據(jù)返回時(shí),必須設(shè)置該參數(shù)為一個(gè)整數(shù),例如:*eof=1;
data
該參數(shù)是內(nèi)核提供給驅(qū)動(dòng)程序的專用指針,可以用于內(nèi)部記錄```
**創(chuàng)建制度的 `/proc` 文件的函數(shù)**
```struct proc_dir_entry *create_proc_read_entry(const char *name,mode_t mode,struct proc_dir_entry *base,read_proc_t *read_proc,void * data)```
參數(shù)說明:
```參數(shù)名
說明
name
要?jiǎng)?chuàng)建 `/proc` 下的文件名
mode
創(chuàng)建的文件權(quán)限的掩碼,若為 0,則使用系統(tǒng)默認(rèn)的權(quán)限
base
該文件所在的父目錄,若該參數(shù)為 null,則該文件將會(huì)被創(chuàng)建在 /proc 的根目錄下
read_proc
讀取 /proc 下的文件時(shí)調(diào)用的函數(shù),也就是前面講解的那個(gè)函數(shù)
data
內(nèi)核會(huì)忽略 date,但會(huì)把該參數(shù)傳遞給 read_proc 函數(shù)```
**刪除 /proc 系統(tǒng)文件的函數(shù)**:
`void remove_proc_entry(const char *name,struct proc_dir_entry *parent)`
參數(shù)說明:
```參數(shù)名
說明
name
在 /proc 文件系統(tǒng)中創(chuàng)建的文件名
parent
父目錄名```
使用 /proc 文件系統(tǒng)的缺點(diǎn)
1. 刪除調(diào)用可能在 `/proc` 文件系統(tǒng)的文件正在被使用時(shí)發(fā)生
2. 同一個(gè)文件名可能注冊(cè)兩次,這將會(huì)發(fā)生錯(cuò)誤
/proc 文件\#cd /proc ; vi read_proc //read_proc 的內(nèi)容如下:
\#include <linux/kernel.h>
\#include <linux/init.h>
\#include <linux/module.h>
\#include <linux/proc_fs.h>
\
int read_proc(char *page,char **start,off_t offset,int count,int *eof,void *data);
\
static int __init test_proc_init(void)
{
create_proc_read_entry("read_proc",0,NULL,read_proc,NULL);
return 0;
}
\
static void __exit test_proc_exit(void)
{
remove_proc_entry("read_proc",NULL);
}
\
int read_proc(char *page,char **start,off_t offset,int count,int *eof,void *data)
{
int len = sprintf(page,"%s\n","hello world");
return len;
}
\
module_init(test_proc_init);
module_exit(test_proc_exit);
\
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wangxq");
\
\#cat /proc/read_proc
hello world
/proc 目錄的應(yīng)用
對(duì)此文件系統(tǒng)的訪問同一般文件相同。
例:
cat /proc/cpuinfo | grep'physical id'|uniq -c|wc –lcat /proc/cpuinfo|grepname|cut -f2 -d:|uniqcat /proc/cpuinfo | grep'physical id'|awk -F':' '{count[$2]++;}END{sum=0;for(a in count){cc++;sum+=count[a]}printsum/cc;}'cat /proc/version|cut-f1 -d'(' cat /proc/stat|grep ctxt|awk'{print $2}'cat /proc/stat|grep processes|awk'{print $2}'cat /proc/meminfo|grep MemFree