日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

UNIX环境编程

發(fā)布時(shí)間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UNIX环境编程 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

linux函數(shù)分析查詢工具

1.優(yōu)先推薦linux 中man命令

2.一個(gè)不錯(cuò)的中文Linux手冊(cè):http://cpp.ezbty.org/manpage

3.在線查英文Man手冊(cè):

http://www.kernel.org/doc/man-pages/

http://man7.org/linux/man-pages/dir_all_alphabetic.html



http://linux.about.com/od/commands/l/blcmdl.htm

http://linux.die.net/man/

http://www.linuxmanpages.com/

man 命令

部分內(nèi)容
man1一般命令。這個(gè)部分中的命令通常不需要超級(jí)用戶(即管理員)特權(quán)。ls、catpasswd 放在這里,還有 shell。例如,請(qǐng)?jiān)囋?man bash。
man2用來(lái)訪問(wèn) UNIX 內(nèi)核提供的服務(wù)的系統(tǒng)調(diào)用或函數(shù)。例如 fork 系統(tǒng),它從一個(gè)現(xiàn)有的進(jìn)程生成一個(gè)新進(jìn)程。輸入 man fork 顯示它的手冊(cè)頁(yè)。使用系統(tǒng)軟件的程序員常常參考這個(gè)部分。
man3C 庫(kù)函數(shù)。許多軟件包提供功能豐富的代碼庫(kù),讓開發(fā)人員可以創(chuàng)建新軟件來(lái)補(bǔ)充現(xiàn)有的特性或開發(fā)全新的特性。每個(gè)庫(kù)通常有一個(gè)手冊(cè)頁(yè);一些庫(kù)(比如系統(tǒng)的 libc)太大了,所以各個(gè)函數(shù)或一組相關(guān)函數(shù)有單獨(dú)的文檔。
man4特殊文件,比如設(shè)備和驅(qū)動(dòng)程序。
man5文件格式。UNIX 幾乎完全使用文本配置文件定制系統(tǒng)的操作。有大量配置文件,包括網(wǎng)絡(luò)服務(wù)的列表 (/etc/services) 和可用的 shell 列表 (/etc/shells) 等等。
man6游戲和屏幕保護(hù)程序。
man7雜類文件。這是一個(gè)包羅萬(wàn)象的類別。在傳統(tǒng)的系統(tǒng)上,可以了解 glob 操作符、正則表達(dá)式等方面的信息。
man8系統(tǒng)管理命令,超級(jí)用戶很可能要使用它們。

在某些情況下,不同部分中的組件可能名稱相同。這種現(xiàn)象很常見,尤其是在一個(gè)軟件包有多個(gè)部分的情況下。例如,第一部分中有 crontab 命令,它提交要調(diào)度的作業(yè)。同時(shí),第五部分中有 crontab 文件格式,它描述要運(yùn)行的作業(yè)。

為了區(qū)分不同部分中的同名組件,應(yīng)該在第一個(gè)參數(shù)中提供部分號(hào):

$ man 1 crontab
$ man 5 crontab

前一個(gè)命令顯示 crontab 命令的手冊(cè)頁(yè);后一個(gè)命令顯示 crontab 文件格式。如果一個(gè)軟件在多個(gè)部分中存在,而您沒(méi)有指定部分號(hào),man 就會(huì)顯示在編號(hào)最低的部分中找到的匹配。


使用-k的man命令可根據(jù)關(guān)鍵字搜索

#man -k fork


看第一行就是我們需要的信息,加上小節(jié)號(hào)

#man 2 fork

從這里我們知道在unistd.h中有fork

該頭文件在/usr/include中

#/usr/include

#vim? unistd.h


庫(kù)函數(shù)和系統(tǒng)調(diào)用的區(qū)別

庫(kù)函數(shù)是高層的,完全運(yùn)行在用戶空間,為程序員提供調(diào)用真正的在幕后完成實(shí)際事務(wù)的系統(tǒng)調(diào)用的更方便的接口。系統(tǒng)調(diào)用在內(nèi)核態(tài)運(yùn)行并且由內(nèi)核自己提供。標(biāo)準(zhǔn)C庫(kù)函數(shù)printf()可以被看做是一個(gè)通用的輸出語(yǔ)句,但它實(shí)際做的是將數(shù)據(jù)轉(zhuǎn)化為符合格式的字符串并且調(diào)用系統(tǒng)調(diào)用 write()輸出這些字符串。

是否想看一看printf()究竟使用了哪些系統(tǒng)調(diào)用? 這很容易,編譯下面的代碼。

#include <stdio.h>
int main(void)
{
printf("hello");
return 0;
}		 

使用命令gcc -Wall -o hello hello.c編譯或者直接cc編譯a.out文件。

用命令

#strace ./hello

或者

#strace ./a.out

跟蹤該可執(zhí)行文件


每一行都和一個(gè)系統(tǒng)調(diào)用相對(duì)應(yīng)。 strace是一個(gè)非常有用的程序,它可以告訴你程序使用了哪些系統(tǒng)調(diào)用和這些系統(tǒng)調(diào)用的參數(shù)、返回值。 這是一個(gè)極有價(jià)值的查看程序在干什么的工具。在輸出的末尾,你應(yīng)該看到這樣類似的一行 write(1, "hello", 5hello)。這就是我們要找的。藏在面具printf() 的真實(shí)面目。既然絕大多數(shù)人使用庫(kù)函數(shù)來(lái)對(duì)文件I/O進(jìn)行操作(像 fopen, fputs, fclose)。 你可以查看man說(shuō)明的第二部分使用命令man 2 write 。man說(shuō)明的第二部分專門介紹系統(tǒng)調(diào)用(像kill()read())。 man說(shuō)明的第三部分則專門介紹你可能更熟悉的庫(kù)函數(shù)(像cosh()random())。



1.getenv

NAME ? ? ? ??

       getenv, secure_getenv - get an environment variable

SYNOPSIS ? ? ? ??

       #include <stdlib.h>char *getenv(const char *name);char *secure_getenv(const char *name);Feature Test Macro Requirements for glibc (see feature_test_macros(7)):secure_getenv(): _GNU_SOURCE

http://man7.org/linux/man-pages/man3/getenv.3.html

函數(shù)說(shuō)明 getenv()用來(lái)取得參數(shù)name環(huán)境變量的內(nèi)容。參數(shù)name為環(huán)境變量的名稱,如果該變量存在則會(huì)返回指向該內(nèi)容的指針。環(huán)境變量的格式為name=value。
返回值:執(zhí)行成功則返回指向該內(nèi)容的指針,找不到符合的環(huán)境變量名稱則返回NULL。


2.putenv

NAME ? ? ? ??

       putenv - change or add an environment variable

SYNOPSIS ? ? ? ??

       #include <stdlib.h>int putenv(char *string);Feature Test Macro Requirements for glibc (see feature_test_macros(7)):putenv(): _SVID_SOURCE || _XOPEN_SOURCE
http://man7.org/linux/man-pages/man3/putenv.3.html

函數(shù)說(shuō)明:putenv()用來(lái)改變或增加環(huán)境變量的內(nèi)容。參數(shù)string的格式為name=value,如果該環(huán)境變量原先存在,則變量?jī)?nèi)容會(huì)依參數(shù)string改變,否則此參數(shù)內(nèi)容會(huì)成為新的環(huán)境變量。
返回值:執(zhí)行成功則返回0,有錯(cuò)誤發(fā)生則返回-1。
錯(cuò)誤代碼:ENOMEM 內(nèi)存不足,無(wú)法配置新的環(huán)境變量空間。


3.setenv

NAME ? ? ? ??

       setenv - change or add an environment variable

SYNOPSIS ? ? ? ??

       #include <stdlib.h>int setenv(const char *name, const char *value, int overwrite);int unsetenv(const char *name);Feature Test Macro Requirements for glibc (see feature_test_macros(7)):setenv(), unsetenv():_BSD_SOURCE || _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
http://man7.org/linux/man-pages/man3/setenv.3.html

函數(shù)說(shuō)明: setenv()用來(lái)改變或增加環(huán)境變量的內(nèi)容。

參數(shù) name為環(huán)境變量名稱字符串。
參數(shù) value則為變量?jī)?nèi)容。

參數(shù) overwrite用來(lái)決定是否要改變已存在的環(huán)境變量。如果overwrite不為0,則改變環(huán)境變量原有內(nèi)容,原有內(nèi)容會(huì)被改為參數(shù)value所指的變量?jī)?nèi)容。如果overwrite為0,且該環(huán)境變量已有內(nèi)容,則參數(shù)value會(huì)被忽略。

返回值: 執(zhí)行成功則返回0,有錯(cuò)誤發(fā)生時(shí)返回-1。

錯(cuò)誤代碼: ENOMEM 內(nèi)存不足,無(wú)法配置新的環(huán)境變量空間


#include <stdio.h>
#include <stdlib.h>
main()
{
char *p;
if((p = getenv("USER")))
printf("USER=%s\n",p);
putenv("USER=root");
printf("USER=%s\n",getenv("USER"));
setenv("USER","test",1);
printf("USER=%s\n",getenv("USER"));
unsetenv("USER");
printf("USER=%s\n",getenv("USER"));
}

輸出:

USER=root
USER=test
USER=test
USER=(null)


4.printf的buffer緩沖

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(void)
{int i;for(i=0; i<2; i++){fork();printf("-");}return 0;
}

注意:輸出8個(gè)-,而不是6個(gè)-

1.fork()系統(tǒng)調(diào)用是Unix下以自身進(jìn)程創(chuàng)建子進(jìn)程的系統(tǒng)調(diào)用,一次調(diào)用,兩次返回,如果返回是0,則是子進(jìn)程,如果返回值>0,則是父進(jìn)程(返回值是子進(jìn)程的pid),這是眾為周知的。

2.還有一個(gè)很重要的東西是,在fork()的調(diào)用處,整個(gè)父進(jìn)程空間會(huì)原模原樣地復(fù)制到子進(jìn)程中,包括指令,變量值,程序調(diào)用棧,環(huán)境變量,緩沖區(qū),等等。

因?yàn)閜rintf(“-”);語(yǔ)句有buffer,所以,對(duì)于上述程序,printf(“-”);把“-”放到了緩存中,并沒(méi)有真正的輸出。在fork的時(shí)候,緩存被復(fù)制到了子進(jìn)程空間,所以,就多了兩個(gè),就成了8個(gè),而不是6個(gè)。

Unix下的設(shè)備有“塊設(shè)備”和“字符設(shè)備”的概念,所謂塊設(shè)備,就是以一塊一塊的數(shù)據(jù)存取的設(shè)備,字符設(shè)備是一次存取一個(gè)字符的設(shè)備。磁盤、內(nèi)存都是塊設(shè)備,字符設(shè)備如鍵盤和串口。塊設(shè)備一般都有緩存,而字符設(shè)備一般都沒(méi)有緩存

對(duì)于上面的問(wèn)題,我們?nèi)绻薷囊幌律厦娴膒rintf的那條語(yǔ)句為: printf("-\n");

或是

printf("-");fflush(stdout);

就沒(méi)有問(wèn)題了(就是6個(gè)“-”了),因?yàn)槌绦蛴龅健癨n”,或是EOF,或是緩中區(qū)滿,或是文件描述符關(guān)閉,或是主動(dòng)flush,或是程序退出,就會(huì)把數(shù)據(jù)刷出緩沖區(qū)。需要注意的是,標(biāo)準(zhǔn)輸出是行緩沖,所以遇到“\n”的時(shí)候會(huì)刷出緩沖區(qū),但對(duì)于磁盤這個(gè)塊設(shè)備來(lái)說(shuō),“\n”并不會(huì)引起緩沖區(qū)刷出的動(dòng)作,那是全緩沖,你可以使用setvbuf來(lái)設(shè)置緩沖區(qū)大小,或是用fflush刷緩存。


參考:http://coolshell.cn/articles/7965.html


fflush用于清空緩沖流,雖然一般感覺(jué)不到,但是默認(rèn)printf是緩沖輸出的。
fflush(stdout),使stdout清空,就會(huì)立刻輸出所有在緩沖區(qū)的內(nèi)容。
fflush(stdout)這個(gè)例子可能不太明顯,但對(duì)stdin很明顯。
如下語(yǔ)句:
int a,c;
scanf("%d",&a);
getchar();
輸入:
12(回車)
那么 a=12 ,c= '\n' 
而:
int a,c;
scanf("%d",&a);
fflush(stdin);
getchar();
輸入:
12(回車)
那么a=12, c暫時(shí)未得到輸入值,還需要再輸入c,因?yàn)間etchar也是緩沖輸入,'\n'本還在緩沖區(qū),但是被清空了。
另外fflush不能作用于重定向輸入流。

5.linux驅(qū)動(dòng)程序中字符設(shè)備和塊設(shè)備的三點(diǎn)區(qū)別

1.字符設(shè)備只能以字節(jié)為最小單位訪問(wèn),而塊設(shè)備以塊為單位訪問(wèn),例如512字節(jié),1024字節(jié)等

2.塊設(shè)備可以隨機(jī)訪問(wèn),但是字符設(shè)備不可以

3.字符和塊沒(méi)有訪問(wèn)量大小的限制,塊也可以以字節(jié)為單位來(lái)訪問(wèn)

參考:http://www.cnblogs.com/qlee/archive/2011/07/27/2118406.html



總結(jié)

以上是生活随笔為你收集整理的UNIX环境编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。