Unix實踐編程入門筆記_第1頁
Unix實踐編程入門筆記_第2頁
Unix實踐編程入門筆記_第3頁
Unix實踐編程入門筆記_第4頁
Unix實踐編程入門筆記_第5頁
已閱讀5頁,還剩71頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第一章Unix系統(tǒng)編程概述

第二章1.2

a)內(nèi)存空間時用來存放程序和數(shù)據(jù)的,所有程序必須需要在內(nèi)存空間中運行

b)而容納操作系統(tǒng)的內(nèi)存空間稱為系統(tǒng)空間,容納應(yīng)用程序的內(nèi)存空間叫做用戶空間

c)操作系統(tǒng)也是一種程序

d)操作系統(tǒng)也稱為內(nèi)核

e)圖L6內(nèi)核管理計算機系統(tǒng)的連接

第三章1.3理解系統(tǒng)編程

a)內(nèi)核提供服務(wù)以方便系統(tǒng)程序可以直接訪問系統(tǒng)資源

b)系統(tǒng)資源

i.處理器:處理指令

ii.輸入輸出(I/O)

iii.進程管理

iv.內(nèi)存

v.設(shè)備

vi.計時器:內(nèi)核可以通過系統(tǒng)調(diào)用向應(yīng)用程序提供計時器服務(wù)

vii.進程間通信

viii.網(wǎng)絡(luò)

c)如何理解:

i.分析程序

ii.學習系統(tǒng)調(diào)用

iii.編程實現(xiàn)

第四章1.4用戶角度理解unix

a)用戶登錄到unix后全部叫個shell進程

b)每個用戶有自己的shell進程

c)目錄操作

d)文件操作

e)unix不支持恢復被刪除的文件功能,因為unix是多用戶系統(tǒng),當一個文件被刪除

掉以后,所占用的內(nèi)存空間可能被立刻分配給其他用戶

f)文件都有三組許可權(quán)限

i.usergroupother

第五章1.5從系統(tǒng)的角度來看unix

第六章1.6動手實踐

a)實現(xiàn)一個more

第二章用戶文件操作與聯(lián)機幫助編寫

who命令

-open

-打開文件是內(nèi)核提供的服務(wù),如果打開過程中內(nèi)核檢測到錯

誤就會返回-1;

■當一個文件已經(jīng)被打開,unix并不禁止一個文件被同時多個

進程訪問

-如果文件被順利打開,內(nèi)核會返回一個正整數(shù)值,即文件描述

符,這個是用來唯一表示進程和文件建立的連接.如果一個文

件被打開多次,所建立的連接不同,文件描述符也不同.

■close系統(tǒng)會調(diào)用關(guān)閉進程和文件fd之間的連接.

■提升文件I/O效率的方法:使用緩沖

■注銷過程

*打開utmp文件

■從utmp中找到包含你所在終端的登陸記錄

■對當前記錄做修改

-關(guān)閉文件

-處理系統(tǒng)調(diào)用中的錯誤

*錯誤種類errno在errno.h中或man3error

#defineEPERM1/*Operationnotpermitted*/

#defineENOENT2/*Nosuchfileordirectory*

#defineESRCH3/*Nosuchprocess*/

#defineEINTR4/*Interruptedsystemcall*/

#defineEIO5/*I/Oerror*/

■不同錯誤需要不同處理

■perror顯示出錯信息

■perror("Cannotopenfile")

第三章目錄與文件屬性

■磁盤上的文件和目錄被組成一個目錄樹,每個節(jié)點都是目錄或文件

-每個文件都位于某個目錄中,在邏輯上沒有驅(qū)動器或者卷

■目錄

■一種特殊的文件類似utmp文件

-是文件的列表,是記錄的序列,每條記錄對應(yīng)一個文件或子目

■通過readdir來讀取目錄中的當前記錄的指針記錄類型為

structdirent

"opendir打開一個目錄

-readdir返回目錄中的當前項

■closedir關(guān)閉一個目錄

,字段編碼

■把多種信息編碼到一個整數(shù)的不同字段中是一種常用技術(shù)

掩碼

■為了比較才巴不需要的地方置零,這種技術(shù)叫做掩碼

masking

■將用戶/組ID轉(zhuǎn)換成字符串

*/etc/passwd包含用戶列表

■/etc/passwd并沒有包括所有的用戶

■/etc/group是組的列表

■UID沒有對應(yīng)的用戶名

-用戶可以同時屬于多個組

■通過getpwuid來得到完整的用戶列表

■通過getgrgid來訪問組列表

■stat

-st_mode成員包含16位,其中四位用作文件類型,9位用作許

可權(quán)限,剩下的三位用作文件特殊屬性.

■三位中的第一位叫做set-user-ID

-SUID經(jīng)常用來給某些程序提供額外的權(quán)限

-可以通過sys/stat.h定義的掩碼來檢驗一個程序是

否有SUID位

■第二位是set-group-ID

■修改文件的權(quán)限

■文件類型

■普通文件,目錄文件,socket文件,符號鏈接文件,命名

管道文件

■文件一旦建立,類型就無法修改

■chown更改文件的用戶

,chown("file",200,20);

-將用戶ID改為200,將組ID改為40

■chgrp修改文件的所有組

■文件大小

-可以用creat將文件大小置0

-時間

■每個文件都有3個時間

-最后修改時間,最后訪問時間和屬性最后修

改時間

-utime系統(tǒng)調(diào)用可以用來設(shè)置最后修改時間和最后

訪問時間

■shell命令touch也可修改文件的最后訪問時間和

最后修改時間

■文件名

■修改文件名

*create(char*old,char*new)

第四章文件系統(tǒng)

?文件操作命令

oInxx-link

■x-link指向x

。In命令的作用是生成一個鏈接

■鏈接是指向文件的一個指針,表明,x-link和x都指向硬盤上的統(tǒng)一數(shù)

據(jù)塊

。ls>x-ling將Is的輸出作為文件x-link的內(nèi)容

?目錄樹的命令

。Is-R列出指定目錄以及其子目錄的所有內(nèi)容

?目錄樹的深度幾乎沒有限制

?Unix文件系統(tǒng)的內(nèi)部結(jié)構(gòu)

。第一層從磁盤到分區(qū)

。第二層從磁盤到塊序列

。第三層,從塊序列到三個區(qū)域的劃分

?unix將磁盤塊分成三個部分任何一部分都由很多有序的磁盤塊組成,文件系統(tǒng)就是

由這三部分組成

。超級塊

-文件系統(tǒng)中的第一塊,被稱為超級塊,存放文件系統(tǒng)本身的結(jié)構(gòu)信息

。i-節(jié)點表

■每個文件的屬性被記錄在i-節(jié)點的結(jié)構(gòu)中,所有節(jié)點具有相同的大小

■每個節(jié)點都通過位置來標識,例如標識為2的節(jié)點位于第三個位置

。數(shù)據(jù)塊

■保存文件的內(nèi)容

?創(chuàng)建一個文件的過程

。存儲屬性

■找到一個空的i-節(jié)點,內(nèi)核將文件的信息記錄在其中

。存儲數(shù)據(jù)

-在內(nèi)核中自由塊中招出3個自由塊

。記錄分配情況

■文件內(nèi)容按順序存放在自由塊中,內(nèi)核在i-節(jié)點的磁盤分布區(qū)記錄了

上述的自由塊序列,

。添加文件名到目錄

■內(nèi)核將接口添加到目錄文件(節(jié)點,filename)

?文件系統(tǒng)的實現(xiàn):目錄的工作過程

??梢酝ㄟ^Is-liademodir來查看目錄的內(nèi)容,輸出的為文件名對應(yīng)的i節(jié)

點號

。Is-i查看一個文件的i節(jié)點號

。對open的每次調(diào)用都是先查找文件名,然后得到節(jié)點號,通過節(jié)點號再得到

文件屬性最終找到文件內(nèi)容

。存在間接塊:存放的是更多磁盤塊

?使用Is-iaR可以列出一棵樹中的所有文件的i節(jié)點號

?如果目錄中有兩個連接的狀態(tài)完全相同,它們稱為指向文件的硬鏈接.內(nèi)核記錄了一

個文件的鏈接數(shù).

?mv僅僅是調(diào)用了系統(tǒng)命令rename

。rename:復制鏈接至新的名字/位置,冊!I除原來的鏈接

?cd調(diào)用了系統(tǒng)函數(shù)chdir

。chdir改變進程的當前目錄,進程有一個存放當前目錄節(jié)點好的變量,從一個

目錄進入兩一個目錄只是改變那個變量的值

?link和rename不可以創(chuàng)建跨域設(shè)備的鏈接和拒絕在不同的文件系統(tǒng)間進行節(jié)點號

的轉(zhuǎn)移.

?df-i命令查看各分區(qū)inode情況

?df-h可以查看各個分區(qū)的使用情況

第五章連接控制:學習sty

?設(shè)備就像文件:

。unix中各種聲卡,終端,鼠標和磁盤文件是同一種對象.每個設(shè)備都有一個文

件名,一個i節(jié)點號,一個文件所有者,一個權(quán)限位的集合和最近修改時間

O

?設(shè)備文件的屬性

。設(shè)備文件和文件大小

■設(shè)備文件是鏈接而不是容器,不存儲擊鍵數(shù)和點擊數(shù).

■設(shè)備文件的i節(jié)點存儲的是指向內(nèi)核的程序的指針,而不是文件大小

和存儲列表

■運行Is/dev/pts/0-al

■輸出在文件大小位置的兩個數(shù)字136,0前者是主設(shè)備號,后者是從

設(shè)備號

-主設(shè)備號:確定除了該設(shè)備實際的子程序

■從設(shè)備號:作為參數(shù)傳輸?shù)皆撟映绦?/p>

。設(shè)備文件和權(quán)限位

■只有文件的所有者有讀的權(quán)限,二同一組的tty成員擁有寫設(shè)備的權(quán)

。設(shè)備文件和i節(jié)點

■文件類型的區(qū)別體現(xiàn)在i-節(jié)點上

■i節(jié)點可以是磁盤文件,也可以是設(shè)備文件,i節(jié)點的類型被記錄在結(jié)

果stat的成員變量st_mode類型區(qū)域中

■read在i節(jié)點先獲取其類型,如果是磁盤文件則通過分配表來讀取

數(shù)據(jù),如果是設(shè)備文件,則調(diào)用該設(shè)備驅(qū)動程序的read部分來讀取數(shù)

據(jù)

?設(shè)備與文件的不同

。磁盤鏈接具有緩沖這樣一個屬性侄U終端的鏈接則不同,進程需要盡快把終端

的數(shù)據(jù)傳送出去

?硬盤鏈接的屬性

O緩沖

■通過修改控制變量改變文件描述符的動作

■例關(guān)閉磁盤緩沖

■生成一個系統(tǒng)調(diào)用,將控制變量從文件描述符復制

到進程

■修改這個復制過來的控制變量

■將新的設(shè)置安置到進程代碼中

o自動添加模式

■為了避免同時對一個文件描述符寫入出現(xiàn)的競爭現(xiàn)象

■當。一APPEND被置位,lseek和write組合成一個原子操作,即不可

分割

■s=fcntl(fd,F_GETEL);

"s|=O_APPEND;

*result=fcntl(fd,F_SETFL,s);

*write(fd,&rec,1);

?終端連接的屬性

。終端驅(qū)動程序

■終端和進程之間由終端驅(qū)動器連接,處理進程和外部設(shè)備間數(shù)據(jù)流的

內(nèi)核子程序被稱為終端驅(qū)動程序,或者tty驅(qū)動程序

ostty命令

■可以讓用戶讀取和修改tty的設(shè)置

ostty關(guān)于設(shè)置

*輸入:

■輸出:

■控制:字符如何表示位的個數(shù),位的奇偶性

■本地:如何處理來自驅(qū)動程序內(nèi)部的字符

第六章終端控制和信號

?軟件工具與針對特定設(shè)備編寫的程序

。對磁盤文件和設(shè)備文件不加以區(qū)分的程序被稱為軟件工具

。事實上大多數(shù)進程自動將前三個文件描述符打開,它們不需要調(diào)用open()來

建立連接

。用戶程序的常用設(shè)置

■立即響應(yīng)擊鍵事件

■有限的輸入集

-輸入的超時

■屏蔽ctrl-c

?終端驅(qū)動程序的模式

。規(guī)范模式

-緩沖和編輯包含規(guī)范處理

■例如回顯,緩沖,編輯才空制處理

。非規(guī)范模式

-stty-icanon

-關(guān)閉回顯,關(guān)閉緩沖這樣輸入什么字符后,將直接傳遞給用戶程序

oraw模式

?阻塞與非阻塞輸入

。當調(diào)用getchar或read從文件描述符讀取輸入時,這些調(diào)用會等待輸入

。阻塞不僅僅是終端連接的屬性,而是任何一個打開的文件的屬性

■程序可以通過fcntl或open為文件描述符啟動非阻塞輸入

■阻塞模式是必須等一個阻塞條件解除后進程才能繼續(xù)執(zhí)行.

■非阻塞模式是不管條件滿不滿足都不停地執(zhí)行下去

?信號

OCtrl-C做了什么

-用戶輸入C-c

■驅(qū)動程序收到字符

■匹配VINTR和ISIG的字符被開啟

■驅(qū)動程序調(diào)用信號系統(tǒng)

-信號系統(tǒng)發(fā)送SIGINT給進程

■進程收到SIGINT

■進程消亡

O每個信號都有一個數(shù)字編碼,中斷信號通常是編碼2

O信號來源

■用戶

■發(fā)送C-c或者其他分配給信號控制字符

*內(nèi)核

■當進程出錯,內(nèi)核給進程發(fā)送一個信號,如非法段存取,浮點數(shù)

溢出

■進程

■一個進程可以和兩一個進程通過信號通信

進程如何處理信號

■默認處理,通常消亡

■忽略信號

■調(diào)用一個函數(shù)

■signal(intsignum,void(*action)(int))

-action可以是函數(shù)名和SIG」GN忽略信號和SIG_DFL將信

號恢復為默認處理兩個之一

■在出程序裝載了signal。函數(shù)后,如果進程遇到對應(yīng)的signal,將會進

入到對應(yīng)的處理函數(shù),然后再跳轉(zhuǎn)到前一個位置,就像子過程調(diào)用

。進程終止

-unix有兩個信號是不能被忽略和捕捉的

第七章事件驅(qū)動編程:編寫一個vedio游戲

?sleep

。linux中的sleep(n)函數(shù)是將當前進程掛起n秒,或者在此期間被一個不能

忽略的信號的到達所喚醒

Osleep是如何工作的

■設(shè)置鬧鐘的秒數(shù)

■睡覺直到鬧鐘響起

。系統(tǒng)中每一個進程都有一個私有的鬧鐘,時間一到,時鐘就發(fā)送一個信號

SIGALARM給進程

osleep函數(shù)

■為SIGALRM設(shè)置一個處理函數(shù)

■調(diào)用alarm(num_seconds);

■調(diào)用pause,動用pause掛起進程直到信號到達,任何信號都可以喚

醒進程,而非僅僅等待SIGALRM

?間隔計時器

。每個進程有3個獨立的計時器,每個計時器都有兩個設(shè)置:初始間隔和重復間

隔.

?添加精度更高的時延usleep

。usleep(n)將進程掛起n微秒,直到一個不能忽略的信號到達

?三種計時器

OITIMER_REAL

■不管程序在用戶態(tài)還是核心態(tài),計時器都會及時,當計時器用盡,發(fā)送

SIGALRM信息

oITIMER_VIRTUAL

■只記錄用戶態(tài)的運行時間,計時器用盡發(fā)送S工GVTALRM消

oITIMER_PROF

-這個計時器在進程運行于用戶態(tài)或由該進程調(diào)用而陷入核心態(tài)時

計時.當這個計時器用盡發(fā)送SIGPROF

?兩種間隔

o初始和重復

-每個間隔計時器的設(shè)置都有這樣兩個參數(shù):初始時間和重復間隔

-it_value和itjnterval

■如果不需要重復將interval設(shè)置為0

■把兩個時鐘都關(guān)掉的話value設(shè)置為0

0通過設(shè)置structitimerval中的值然后將這個結(jié)構(gòu)體通過調(diào)用setitimer

傳給計時器,讀取計時器的設(shè)置用getitimer

?計算機有幾個時鐘

。每當內(nèi)核收到系統(tǒng)時鐘脈沖,它遍歷所有的間隔計時器,使每個計數(shù)器減一個

時鐘單位,如果進程A的計數(shù)器達到0的時候,內(nèi)核發(fā)送SIGALRM給進程A.

如果進程A已經(jīng)設(shè)置了計時器的itjnterval值,內(nèi)核將這個值復制到

it_value計數(shù)器.否則關(guān)掉這個計數(shù)器

?信號處理:使用signal

。POSIXUnix型可移植操作系統(tǒng)接口的信號處理模型

0處理多個信號

-捕鼠器,當信號或老鼠被捕獲,信號處理函數(shù)或捕鼠器就失效,再每次

捕獲后需要重新設(shè)置

■不可靠的信號

-兩個sigints殺死進程

-sigy打斷sigx的處理函數(shù)

■sigx打斷sigx的處理函數(shù)

■遞歸調(diào)用同一個處理函數(shù)

-忽略第二個信號

-阻塞第二個信號直到第一個處理完畢

■被中斷系統(tǒng)調(diào)用

。信號機制其他弱點

■不知道信號被發(fā)送的原因,只知道是什么類型的信號

■處理函數(shù)中不能安全的阻塞其他消息

?處理多個信號sigaction

o#include<stdio.h>

o#include<signal.h>

o#include<unistd.h>

o

ointi=0;

ointmain(intargqconstchar*argv[])

o(

ostructsigactionnewhandler;

osigset_tblocked;

ovoidinthandlerO;

ocharx[128];

o

onewhandler.sa_handler=inthandler;

onewhandler.sa_flags=SA_RESTART;

o

osigemptyset(&blocked);

osigaddsetf&blocked,SIGQUIT);

onewhandler.sa_mask=blocked;

o

=二

oif(sigaction(SIGINTz&newhandlerzNULL)-1)

operror("sigactiondown");

oelse{

owhile(1){

ofgets(x,128,stdin);

oprintf("input:%s\n",x);

o)

o)

oreturn0;

o)

o

ovoidinthandlerO

o(

o++i;

ointx=i;

oprintf("Calledwithsignal%d\n"zx);

osleep(x);

oprintf("okthissignal%ddone\n",x);

osleep(x);

o)

?防止數(shù)據(jù)損毀

O臨界區(qū)

■一段修改一個數(shù)據(jù)結(jié)構(gòu)的代碼如果在運行時被打斷,將導致數(shù)據(jù)的不

完整或損毀,這段代碼稱為臨界區(qū)

■在程序處理信號的時候必須決定那一段代碼是臨界區(qū)并設(shè)法保護

-保護臨界區(qū)的簡單方法就是阻塞和忽略將要使用或修改特定數(shù)據(jù)的

信號

o阻塞信號sigprocmask和sigsetops

■處理一個信號阻塞另一個要設(shè)置sa_mask位是sigset_t類型定義

了一個信號集

■信號擋板

■任何時候一個進程都有一些信號被阻塞,這個信號集就是信

號擋板

"sigprocmask可以修改這個信號集

■sigprocmask(inthow,sonstsigset_t*sigs,sigset_t

*prev);

-how如何修改信號擋板,依次是添加刪除和替換

-SIG_BLOCK

■SIG_UNBLOCK

■SIG_SET

■sigs指向信號列表的指針

■prev指向之前的信號擋板的指針或者是null

■用sigsetops構(gòu)造信號集

■sigemptyset(sigset_t*setp)清除setp指向的所有信號

■sigfillset(sigset_t*setp)添加所有信號到setp指向的列表

■sigaddset(sigset_t*setp,intsignum)添力口signum至!]

setp指向的列表

-釋放資源時恢復獲取時的狀態(tài)是個好習慣

。重入代碼

■可重入

-如果一個函數(shù)或者信號處理在激活狀態(tài)下能被調(diào)用并且不

引起任何問題就稱之為可重入的

■在sigaction設(shè)置時設(shè)置為SA_NODEFER來允許函數(shù)遞

歸調(diào)用,反之清除此位來阻塞信號

-如果處理不可重入則必須阻塞信號,如果阻塞則有可能丟失

信號

。kiH:從另一個進程發(fā)送信號

■一個進程可以通過kill系統(tǒng)調(diào)用向另一個進程發(fā)送信號

"intkill(pid_tpid,intsig)

-pid目標進程pid

■sig要被發(fā)送的信號

■返回值:-1失敗,0成功

?輸入信號:異步10

。硬件實現(xiàn)

第八章編寫sh學習進程

?PS就是運行中的程序

。WCHAN程序休眠的原因

?進程管理與文件管理

。文件包含數(shù)據(jù)

。進程包含可執(zhí)行代碼

?內(nèi)存和程序

。內(nèi)存可看做由頁面構(gòu)成的數(shù)組,將進程分割到不同的頁面

。一個進程不一定必須占用連續(xù)的內(nèi)存

。內(nèi)核要找到一些用來存放程序指令和數(shù)據(jù)的空閑內(nèi)存頁,內(nèi)核還要建立數(shù)據(jù)

結(jié)構(gòu)來存放相應(yīng)的內(nèi)存分配情況和進程屬性

?shell的功能

。shell進程控制和程序控制的一個工具

。運行程序

-shell將應(yīng)用程序載入內(nèi)存并運行,程序啟動器

。管理輸入和輸出

■shell可以用<>|來將輸入輸出重定向,這樣就可以告訴shell將進

程的輸入輸出連接到一個文件或是其他的進程

。編程

■shell帶有變量和流程控制的編程語言

shell如何運行程序

o用戶鍵入a.out

。shell建立一個新的進程來運行這個程序

。shell將程序從磁盤載入

。程序在它的進程中運行直到結(jié)束

。即學會

。運行一個程序

。建立一個進程

o等待exit()

?一個程序如何調(diào)用另一個程序

Oexecvp("progname",arglist)將指定的程序復制到調(diào)用它的進程

。exc系統(tǒng)調(diào)用從當前進程中把當前程序的機器指令刪除,然后在空的進程中

載入調(diào)用指定的程序代碼,最后運行這個新的程序,exec調(diào)整進程的內(nèi)存分

配,相同進程,不同內(nèi)容

?如何建立新的進程

。一個進程調(diào)用fork來復制自己

-分配新的內(nèi)存塊和內(nèi)核數(shù)據(jù)結(jié)構(gòu)

■復制原來的進程到新的進程

■向運行進程集添加新的繼承

■將控制返回給兩個進程

。新的進程從fork返回的地方開始運行

。fork。在子進程中返回的是0,在父進程返回子進程的進程號

?父進程如何等待子進程退出

。進程調(diào)用wait等待子進程結(jié)束

o解釋wait。

■wait掛起調(diào)用它的進程直到得到這個進程的子進程的一個結(jié)束狀

態(tài),wait返回結(jié)束進程的pid,如果調(diào)用的進程沒有子進程也沒有得到

終止狀態(tài)值,wait返回-1

■wait暫停調(diào)用它的進程直到子進程結(jié)束,然后wait取得子進程結(jié)束

時傳給exit的值

-最終子進程會結(jié)束任務(wù)并調(diào)用exit(n)n是0-255的一個數(shù)字

■intstatus

■wait(&status),最終status的值就是exit(n)中的n

。例

-pid=fork()

■switch(pid):

-case-1:

*perror("forkfailed!");

*exit(-l);

■case0:〃說明是子進程

■execvp("ls",arglist);

-perror("execvpfailed!")〃如果運行無誤的話子進程是運

行不到此部分的

■exit(-l);

default:

■while(wait(NULL)!=pid);

。退出主進程的辦法只能是ctrl-c但是如果在子進程等待的時候按了ctrl-c

則會將兩個進程全部殺死

。因為鍵盤信號發(fā)給所有連接的進程,可以通過之前學習的知識裝填相應(yīng)的信

號處理函數(shù)對相應(yīng)進程收到的信號進行處理

。unix提供方法來建立全局變量.即是利用環(huán)境

?exit和exec的其他細節(jié)

。那些已經(jīng)死亡但是沒有exit賦值的進程為僵尸進程,ps會將其列為defunct

。系統(tǒng)調(diào)用一exit。

■關(guān)閉所有的文件描述符和目錄描述符

-將P工D置為init進程的P工D

-如果父進程調(diào)用wait或者waitpid來等待子進程結(jié)束,

則通知父進程

■向父進程發(fā)送SIGCHLD

■如果子進程的父進程退出了,子進程也會繼續(xù)運行,并成為init進程的

子進程

?exec家族

oexecl()I是list的意思

"execl(fullname,argO,argl,...);

。execIpQp是path的意思會在環(huán)境變量PATH中來找第一個參數(shù)指定的

程序

-execlp(filename,argO,argl,...);

第九章可編程的shellshell變量和環(huán)境

?shell的編程特征

o變量,I/O和if...then

。shell腳本是真正的程序

?shell命令中除了命令還有

。變量

-一般用大寫并用$來獲取變量的值

。用戶輸入

■read命令告訴shell要從標準輸入讀入一個字符串可以用read來創(chuàng)

建交互的腳本,也可以從文件或者管道中讀數(shù)據(jù)

。控制

■if..then?elsefi..whilecasefor

O環(huán)境

-即Shell可以使用環(huán)境變量的值

?shell中的流程控制

。if語句的作用是條件檢測,如果條件符合則有一部分代碼被執(zhí)行‘

。shell中條件是一個命令,返回正值意味著命令運行成功

。exit(O)代表成功,if.then語句基于以0退出表示成功這個假設(shè)

。if是如何工作的

■shell運行if之后的命令

■shell檢查exit狀態(tài)

?shell變量局部和全局

o賦值var=value#不能有空格

o$var引用

ounsetvar刪除

oreavar輸入

oset列出變量

oexportvar全局化

。變量名不能使數(shù)字開頭,變量都是字符串,

?變量存儲

。模型

■需要有存放的文件夾,來存放變量的名字和值

。接口

■VLstore(char*var,char*val)增加更新var=val

■VLookup(char*var)取得var值

■VList輸出列表到stdout

。實現(xiàn)

■可以用鏈表,hash表,樹或者任何數(shù)據(jù)結(jié)構(gòu)來實現(xiàn).

?環(huán)境個性化設(shè)置

。環(huán)境不是shell一部分

。env命令列出當前所有的環(huán)境設(shè)置,env不是shell的命令而是一個應(yīng)用程

Oset列出所有的shell定義的變量set是shell的命令

。使用標準庫函數(shù)getenv也可獲得環(huán)境變量的值

■char*cp=getenv("LANG");

?什么是環(huán)境

。環(huán)境是每個程序都可以存儲的一個字符串數(shù)組

?fork產(chǎn)生的子進程會完整的復制其父進程的代碼數(shù)據(jù),數(shù)據(jù)包括環(huán)境,exec清楚了原

來進程中的所有代碼和數(shù)據(jù)

?只有通過參數(shù)execvp傳遞的數(shù)據(jù)和村住在環(huán)境中的字符串可以從舊程序復制到新

程序中

?子進程不能修改父進程的環(huán)境

第十章I/O重定向和管道

?命令who|sort>prev告訴who的輸出直接送到sort但是who命令并不一定

要在sort命令開始讀取和排序之前完成utmp的分析,這兩個進程以很小的時間間

隔為單位來調(diào)度,他們和系統(tǒng)的其他進程一樣分享CPU時間

?unix的工具comm可以找出兩個文件中共有的行,

。結(jié)果是三個子集,僅有文件1有的行,僅文件2有的行,兩者共有的,

。可以通過刪除某一列或者兩列來顯示需要的結(jié)果

"comm-23prevcurr//刪除二三列,即只顯示prev內(nèi)容

■comm-13prevcurr〃刪]除一三列,即只顯示curr內(nèi)容

?重定向標準I。的若干概念

0重定向

"unixio重定向都是基于標準數(shù)據(jù)流的原理

■sort三個數(shù)據(jù)流分別如下

■標準輸入-需要處理的數(shù)據(jù)

■標準輸出-結(jié)果數(shù)據(jù)流

■標準錯誤輸出-錯誤消息流

■三個標準文件描述符

■0:stdin

*l:stdout

*2:stderr

■unix假設(shè)上述三個文件描述符已經(jīng)被打開了可以分別進

行讀寫

■一般大多數(shù)程序不接收輸出文件名,他們總是將結(jié)果寫到文

件描述符1中區(qū),將錯誤信息寫的文件描述符2.如果需要寫

到文件或者另一個進程的輸入,就必須重定向相應(yīng)的文件描

述符

■默認連接tty

-大部分unix工具處理從文件或標準輸入讀入的數(shù)據(jù),如果

在命令行上給出了文件名,工具將從文件讀取數(shù)據(jù).如果沒有

文件名,則從stdin來讀入數(shù)據(jù)

,重定向10的是shell而不是程序

*通過重定向標志,cmd>filename

■重要的一點是shell并不將重定向標記和文件名傳遞給程

"">"并不能終止命令和參數(shù),它只不過是一個附加的請求而

■shell提供對重定向其他文件描述符的支持,例如

2>filename重定向文件描述符2到給定的文件中

■最低可用文件描述符原則

■概念

■當打開文件時,為此文件安排的文件描述符總是此數(shù)

組中最低可用位置的索引.

■文件描述符:是一個數(shù)組的索引號.

■每個進程都有其打開的一組文件,這些打開的文件被保持在

一個數(shù)組中

。如何將stdin重定向文件

■dup

■復制一個文件描述符

*newfd=dup(oldfd);

■newfd=dup2(oldfd,newfd);

■dup復制文件描述符。Idfd

■dup2將oldfd文件描述符復制給newfd,兩個文件描述符

都指向一個打開的文件.

■進程并不是從文件讀數(shù)據(jù),而是從文件描述符讀數(shù)據(jù),如果將文件描

述符定位到一個文件,那么這個文件就成為標準輸入的源

■方法lclosethenopen

-1掛斷描述符0

-2使用open(filename,O_RDONLY)打開一個文件,當前

最低可用文件描述符是0因此打開的文件在文件描述符0

■方法2open..close..dup..close

-unix系統(tǒng)調(diào)用dup建立一個已經(jīng)存在的文件描述符的第二

個連接.

■1open(file)打開一個需要被重定向的文件,返回一個并不

是0的文件描述符

-2close(0)讓0文件描述符空虛

-3dup(fd)江文件描述符做一個復制,此次復制使用了最低

的可用文件描述符也就是0

■4close(fd)關(guān)閉之前的文件描述符

■方法3open..dup2..close

*dup2(fd,0)可用來替換close(O)和dup(fd)

■用exec執(zhí)行新程序后,原來程序的代碼和數(shù)據(jù)都被替代了,然而打開

的文件并不屬于程序的代碼和數(shù)據(jù),它們屬于進程的屬性,

■在子進程中利用

*close(l)

■create(f)

■exec("who")

■就可以將Who的輸出弄到f中了

?管道編程

。使用管道可以連接一個進程的輸出和另一個進程的輸入

。管道是內(nèi)核中的一個單向的數(shù)據(jù)通道,包括一個讀取端,一個寫入端

。創(chuàng)建管道

■pipe<intarray[2]>

■array[O]為讀數(shù)據(jù)段的文件描述符

"array[l]為寫數(shù)據(jù)段的文件描述符

。使用fork來共享管道

.圖10.20共享管道

-兩個進程都可以讀寫管道,但是一個進程讀,另一個進程寫的時候管

道的使用效率最高

。技術(shù)細節(jié)管道并非是文件

■管道許多方面類似普通文件,進程使用write將數(shù)據(jù)寫入管道,又通過

read把數(shù)據(jù)讀出來.

■管道是不帶有任何結(jié)構(gòu)的字節(jié)序列

■從管道中讀數(shù)據(jù)

■管道讀取阻塞

■當進程試圖從管道中讀數(shù)據(jù)時,進程被掛起,知道數(shù)

據(jù)被寫進管道

-管道讀取結(jié)束標志

■當所有的寫者關(guān)閉管道的寫數(shù)據(jù)端時,試圖從管道讀

取數(shù)據(jù)的調(diào)用返回0

-多個讀者可能會引起麻煩

■管道是一個隊列.

■當進程從管道中讀取數(shù)據(jù)之后,數(shù)據(jù)已經(jīng)不存在了.

■如果兩個進程試圖對同一個管道進行讀操作,在一個

進程讀取一些之后,另一個進程讀到的是將是后面的

內(nèi)容

向管道中寫數(shù)據(jù)

■寫入數(shù)據(jù)阻塞直到管道有空間去容納新的數(shù)據(jù)

■管道容納數(shù)據(jù)的能力要比磁盤文件差的多.當進程試

圖對管道進行寫操作的時候,此調(diào)用將掛起知道管道

中有足夠的空間去容納新的數(shù)據(jù).

■寫入必須保證一個最小塊的大小

-POSIX標準規(guī)定內(nèi)核不會拆分小于512字

節(jié)的塊.

-linux保證管道中可以存在4096字節(jié)的連

續(xù)緩存

-如果兩個進程向管道寫數(shù)據(jù),并且每個進程

都限制其消息不大于512字節(jié),那么這些消

息不會被內(nèi)核拆分

-若無讀者在讀取數(shù)據(jù),則寫操作執(zhí)行失敗

-如果所有的讀者都將管道的讀取端關(guān)閉,那

么對管道的寫入調(diào)用將會執(zhí)行失敗.

-為了避免這種情況下的數(shù)據(jù)丟失,內(nèi)核采用

兩種方法來通知進程

■內(nèi)核發(fā)送SIGPIPE消息給進程

■write調(diào)用返回-1并且將errno置

為EPIPE

第十一章連接到近端或遠端的服務(wù)器與

socket套接字

?unix各種數(shù)據(jù)源

4種類型的數(shù)據(jù)源

1.磁盤文件

2.設(shè)備

3.管道

4.Sockets

使用同一個I/O接

o圖11.2一個接口和不同的數(shù)據(jù)源

。1,2磁盤/設(shè)備文件

■open命令連接,用read和write傳遞數(shù)據(jù)

O3管道

*用pipe創(chuàng)建fork共享,read和write傳遞數(shù)據(jù)

o4sockets

■用socket,listen和connect連接read和write傳遞數(shù)據(jù)

?be是unix中是用的計算器

。但是be并不是一個計算器,be內(nèi)部啟用了de計算器程序,并通過管道進行通

信.

?be思想

。客戶/服務(wù)器模型思想

■de提供服務(wù):計算

-be和de之間通過標準輸入和標準輸出進行通信,be稱為de的客戶

。雙向通信

■傳統(tǒng)的unix管道只能單方向的傳送數(shù)據(jù)

■c/s模型不同于生產(chǎn)線的數(shù)據(jù)處理模型,它要求一個進程既跟一個進

程的標準輸入也要和它的標準輸出進行通信,

■be和de之間有兩個管道,其中一個管道將計算命令傳給de的標準

輸入,另一個管道吧de的標準輸出傳給be

。永久性服務(wù)

■be只是讓單一的de進程處于運行狀態(tài),這就不同于shell程序,這種

程序中的每個用戶命令都創(chuàng)建一個新的進程

-bc/dc對被稱之為協(xié)同進程be程序不斷地同一個de實例進行通信,

把用戶的輸入轉(zhuǎn)換成命令傳給de

?協(xié)同進程的討論

。一個客戶/服務(wù)器模型程序要成為協(xié)同系統(tǒng)必須有明確指明消息結(jié)束的方法,

并且程序必須使用簡單并可預測的請求和應(yīng)答

?fdopen

。與fopen雷系,返回一個FILE*類型的值,不同的是此函數(shù)可以通過文件描述

符而非文件作為參數(shù)

?popen:讓進程看似文件

。popen的功能

■打開一個指向進程的帶緩沖的連接

-FILE*fp;

"fp=popen("ls","r");

■fgets(buf,len,fp);

pclose(fp);

popen("Is","r")

o實現(xiàn)popen

■sh支持-c選項用以告訴shell執(zhí)行某命令后退出

■需要一個新的進程所以用到fork

-需要一個指向該進程的連接需要管道

■需要一個文件描述符定向到緩沖流需要fdopen

■需要在進程中執(zhí)行shell用到exec

。訪問數(shù)據(jù)

-文件,API和服務(wù)器

■從文件獲得數(shù)據(jù)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論