国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

Linux會(huì)話淺析

2019-11-11 02:57:32
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
說(shuō)起會(huì)話,我們經(jīng)常登錄到linux系統(tǒng),執(zhí)行各種各樣的程序,這都牽涉到會(huì)話。但是,一般情況下我們又很少會(huì)去關(guān)注到會(huì)話的存在,很少會(huì)去了解它的來(lái)龍去脈。本文就對(duì)linux會(huì)話相關(guān)的信息做一些整理,看看隱藏在我們?nèi)粘J褂玫谋澈螅加行┦裁礃拥倪壿嫛!緯?huì)話的維系】維系一個(gè)會(huì)話,最常見(jiàn)的有兩種方式:一是基于某種憑證,比如web網(wǎng)站的登錄會(huì)話,在登錄驗(yàn)證之后,服務(wù)器就會(huì)返回一個(gè)session id作為憑證。用戶之后的請(qǐng)求總是會(huì)帶上這個(gè)id,而服務(wù)器通過(guò)這個(gè)id也就能知道用戶是誰(shuí)。直到用戶注銷(xiāo)登錄、或者登錄超時(shí),服務(wù)器會(huì)清洗掉對(duì)應(yīng)的session id,這個(gè)id就失效了,會(huì)話也就隨之而結(jié)束。第二種方式是基于連接的,當(dāng)用戶和系統(tǒng)之間的連接啟用時(shí),系統(tǒng)會(huì)對(duì)用戶進(jìn)行驗(yàn)證,驗(yàn)證通過(guò)之后,來(lái)自這個(gè)連接的操作都是屬于這個(gè)用戶的。直到連接斷開(kāi),則會(huì)話結(jié)束。linux系統(tǒng)的會(huì)話就是以第二種方式來(lái)維系的。會(huì)話基于連接,那么連接的安全性就決定了會(huì)話的安全性。以最常見(jiàn)的兩種連接為例:1、本地連接,用戶是直接通過(guò)鍵盤(pán)顯示器來(lái)跟系統(tǒng)交互的,鍵盤(pán)顯示器直接連接在主機(jī)上,連接被篡改基本上是不可能的;2、遠(yuǎn)程連接,以ssh為例,其協(xié)議會(huì)進(jìn)行加密,從而避免連接被篡改;下面在討論會(huì)話的時(shí)候就圍繞兩種連接來(lái)展開(kāi)。【連接的啟用】前面說(shuō)到,會(huì)話是基于連接的。會(huì)話的源頭,就是用戶與系統(tǒng)之間連接的啟用。對(duì)于本地連接,連接是在系統(tǒng)初始化時(shí)建立的。linux會(huì)初始化若干個(gè)tty(/dev/tty?),形成若干個(gè)虛擬終端。本地連接的鍵盤(pán)和顯示器通過(guò)對(duì)應(yīng)的驅(qū)動(dòng)程序,跟其中某個(gè)tty綁定上。用戶可以通過(guò)ALT+F[1-12]鍵,將鍵盤(pán)和顯示器切換到不同的tty上(也就是說(shuō),一套鍵盤(pán)顯示器可以對(duì)應(yīng)多個(gè)本地連接)。在系統(tǒng)啟動(dòng)的時(shí)候,init程序會(huì)根據(jù)相應(yīng)的配置(如:/etc/init/tty1.conf),啟動(dòng)相應(yīng)的程序來(lái)監(jiān)聽(tīng)這些tty(如:/sbin/getty -8 38400 tty1。下文說(shuō)到這個(gè)監(jiān)聽(tīng)程序時(shí),就以getty為例)。當(dāng)用戶通過(guò)ALT+F?切換到對(duì)應(yīng)的tty?、并有所輸入時(shí),在該tty上監(jiān)聽(tīng)的getty就能讀取到輸入信息,然后通過(guò)exec啟動(dòng)login程序來(lái)進(jìn)行登錄驗(yàn)證。從getty得到輸入的這一刻起,tty?上的這個(gè)連接就算是啟用了。對(duì)于遠(yuǎn)程連接,本文都以ssh為例。系統(tǒng)安裝ssh server之后,在/etc/init.d/下會(huì)有它對(duì)應(yīng)的啟動(dòng)腳本,這會(huì)使得sshd程序(ssh服務(wù)器)在系統(tǒng)啟動(dòng)的時(shí)候被啟動(dòng)(當(dāng)然,root用戶也可以在系統(tǒng)啟動(dòng)之后,手動(dòng)啟動(dòng)sshd)。sshd監(jiān)聽(tīng)網(wǎng)絡(luò)上的相應(yīng)端口(如:tcp:22),等待遠(yuǎn)程用戶的連接。用戶的連接始于TCP連接,然后sshd和ssh-client會(huì)打通ssh隧道。從這時(shí)起,連接啟用,sshd會(huì)要求用戶進(jìn)行登錄驗(yàn)證。【登錄驗(yàn)證】不管是本地終端登錄,還是遠(yuǎn)程登錄,登錄驗(yàn)證無(wú)非就是要讓用戶輸入用戶名和密碼。用戶輸入的信息通過(guò)已經(jīng)啟用的連接到達(dá)對(duì)端程序(如:login、sshd),然后由其進(jìn)行校驗(yàn)。系統(tǒng)中的用戶信息存放在/etc/passwd文件中,里面保存的系統(tǒng)中所有用戶的信息。這些信息主要有:用戶名、密碼、組、home路徑、以及登錄后執(zhí)行的程序、等。這些信息可以分兩個(gè)層面來(lái)看:一、用于驗(yàn)證的。包括用戶名和密碼兩項(xiàng)。即用戶在與系統(tǒng)建立連接后,需要提供用戶名和密碼來(lái)進(jìn)行驗(yàn)證(注意,密碼一般并不是明文保存在passwd文件中的);二、登錄后用于設(shè)置用戶屬性的。除密碼外的所有項(xiàng)。下面會(huì)詳細(xì)解釋?zhuān)挥脩舻卿浐髸?huì)得到一個(gè)進(jìn)程,關(guān)于這個(gè)進(jìn)程,它有如下一些特征:1、對(duì)于本地連接,它就是原本執(zhí)行g(shù)etty的那個(gè)進(jìn)程;而對(duì)于ssh連接,它是由sshd fork出來(lái)的進(jìn)程;2、進(jìn)程的用戶名、組、當(dāng)前路徑、等都被按/etc/passwd文件中的描述進(jìn)行設(shè)置;3、進(jìn)程的stdin、stdout、stderr連接到一個(gè)對(duì)應(yīng)的終端。對(duì)于本地連接,這個(gè)終端就是getty監(jiān)聽(tīng)的那個(gè)tty;對(duì)于ssh連接,它是由sshd打開(kāi)的pty(偽終端,后面會(huì)詳細(xì)解釋?zhuān)?、這個(gè)進(jìn)程會(huì)執(zhí)行/etc/passwd中配置的"登錄后執(zhí)行的程序",這個(gè)程序一般就是/bin/sh,即登錄后為用戶提供一個(gè)shell控制臺(tái)。于是用戶可以使用自己的終端跟這個(gè)shell程序交互,干各種事情。這個(gè)"登錄后執(zhí)行的程序"也常被配置為/bin/nologin,表示對(duì)應(yīng)用戶是不允許登錄的,因?yàn)閚ologin程序不會(huì)與用戶進(jìn)行交互,打印錯(cuò)誤信息后就會(huì)退出了,所以登錄只是白費(fèi)勁。當(dāng)然,如果你愿意,并且有root權(quán)限,也可以將"登錄后執(zhí)行的程序"配置成其他程序;于是,用戶在登錄完成之后,系統(tǒng)中就存在這樣一個(gè)用戶名為該登錄用戶的進(jìn)程。通常這個(gè)進(jìn)程運(yùn)行shell程序,并且其輸入輸出連接到用戶的終端,所以用戶可以用鍵盤(pán)來(lái)操作這個(gè)shell,并且用顯示器接收shell的輸出。【關(guān)于終端】前面講到,登錄后的shell其輸入輸出是連接到用戶使用的終端的,不管是本地登錄的tty,還是遠(yuǎn)程登錄的pty。但是,為什么要有終端呢?shell的輸入直接接到鍵盤(pán)、輸出直接接到顯示器,這樣不行么?尤其是遠(yuǎn)程的情況,shell的輸入輸出為什么不能直接接到網(wǎng)絡(luò),而非要弄一個(gè)pty出來(lái)呢?最容易想到的一點(diǎn),終端能夠使得上層不必關(guān)心輸入輸出設(shè)備本身的細(xì)節(jié),只管對(duì)其讀寫(xiě)就行了。不過(guò)這一點(diǎn)似乎并不是終端所特有的,因?yàn)関fs已經(jīng)能夠勝任了。應(yīng)用程序open設(shè)備文件,得到fd,然后同樣只用管對(duì)其讀寫(xiě)就行了,而不用關(guān)心這個(gè)fd代表的是鍵盤(pán)、還是普通文件,具體的細(xì)節(jié)已經(jīng)被隱藏在設(shè)備驅(qū)動(dòng)程序之中。不過(guò),相比于普通的讀寫(xiě),終端還實(shí)現(xiàn)了很多可以通過(guò)ioctl系統(tǒng)調(diào)用進(jìn)行配置的功能,能夠完成一些針對(duì)輸入輸出的處理邏輯。如:1、回車(chē)換行的轉(zhuǎn)換:定義輸入輸出如何映射回車(chē)換行符。比如:回車(chē)鍵是/r、還是/n、還是/r/n;再如:/n應(yīng)該如何打印到屏幕上,是回車(chē)+換行、還是只換行不回車(chē)、等等;2、行編輯:允許讓輸入字符不是立馬送到應(yīng)用程序,而是在換行以后才能被讀取到。未換行的輸入字符可以通過(guò)退格鍵進(jìn)行編輯(比如在你密碼輸錯(cuò)的時(shí)候,是可以用CTRL+退格來(lái)進(jìn)行編輯的);3、回顯:可以讓輸入字符自動(dòng)被回顯到終端的輸出上。于是,鍵盤(pán)每輸入一個(gè)字符都能在顯示器上看到它,而這些字符其實(shí)很可能是還沒(méi)被應(yīng)用程序讀取到的(因?yàn)橛行芯庉嫞?、功能鍵:允許定義功能鍵。比如最常用的Ctrl+C,殺死前臺(tái)進(jìn)程,就是由終端來(lái)觸發(fā)的。終端檢測(cè)到Ctrl+C輸入,會(huì)向前臺(tái)進(jìn)程組發(fā)送SIGTERM信號(hào)。而誰(shuí)是前臺(tái)進(jìn)程組呢?這是由shell通過(guò)ioctl系統(tǒng)調(diào)用對(duì)終端使用TIOCSPGRP命令來(lái)設(shè)置的,每當(dāng)shell啟動(dòng)一個(gè)前臺(tái)進(jìn)程,它都需要這么設(shè)置一下;5、輸入輸出流向控制,只有前臺(tái)進(jìn)程組能夠從終端中讀數(shù)據(jù)、而不管前臺(tái)后臺(tái)程序都能向終端寫(xiě)數(shù)據(jù)。這點(diǎn)也是必須的,跟用戶進(jìn)程交互的是前臺(tái)進(jìn)程,用戶的輸入當(dāng)然不能被其他后臺(tái)進(jìn)程搶走。但是一個(gè)進(jìn)程是前臺(tái)還是后臺(tái),是它自己是所不知道的,沒(méi)法靠進(jìn)程自己來(lái)判斷什么時(shí)候可以讀終端、什么時(shí)候不能讀。所以需要終端來(lái)提供支持,如果后臺(tái)進(jìn)程讀這個(gè)終端,終端的驅(qū)動(dòng)程序?qū)⑾蚱浒l(fā)送SIGTTIN信號(hào),從而將其掛起。直到shell將其重新置為前臺(tái)進(jìn)程時(shí)(通過(guò)fg命令),該進(jìn)程才會(huì)繼續(xù)執(zhí)行;6、等等;終端提供的這些功能未必都會(huì)被打開(kāi)它的程序使用到,但是如果要使用,則可以通過(guò)統(tǒng)一的ioctl接口來(lái)設(shè)置,而不需要關(guān)心終端具體接的是什么設(shè)備,是鍵盤(pán)顯示器?還是網(wǎng)絡(luò)。大多數(shù)應(yīng)用程序則根本不關(guān)心終端,只當(dāng)它是能夠滿足讀寫(xiě)需求的文件。而像shell這樣為人機(jī)交互而生的程序,則注定會(huì)跟終端打交道。對(duì)于shell來(lái)說(shuō),像“行編輯”、“回顯”這樣的功能,其實(shí)是可以不需要依賴終端的,shell程序自己可以做這樣的處理,因?yàn)橐鎏幚淼臄?shù)據(jù)正是shell從終端里面讀到的數(shù)據(jù)。但是像“功能鍵”、“輸入輸出流向控制”這樣的功能,則又不得不依賴終端。比如“功能鍵”,因?yàn)檫@時(shí)在對(duì)終端進(jìn)行讀操作的是shell啟動(dòng)的前臺(tái)程序,而不是shell自己,所以不可能由shell來(lái)讀取功能鍵,然后觸發(fā)信號(hào)。可以說(shuō),終端是人機(jī)交互時(shí),應(yīng)用程序與用戶之間的一個(gè)中間層。如果應(yīng)用程序是在跟人交互,使用終端是其不二的選擇;否則則沒(méi)有必要使用終端。這一點(diǎn)在sshd上面有很好的體現(xiàn)。當(dāng)用戶使用ssh登錄到遠(yuǎn)程機(jī)器remotehost,并執(zhí)行一些操作時(shí)(比如執(zhí)行cat test.txt操作),可以有兩種方式:1、ssh user:pass@remotehost,遠(yuǎn)程登錄后,再在shell中執(zhí)行cat test.txt命令;2、ssh user:pass@remotehost 'cat test.txt',直接由sshd啟動(dòng)一個(gè)shell、自動(dòng)執(zhí)行'cat test.txt'命令;第一種方式,是登錄之后,再通過(guò)人機(jī)交互輸入命令,這時(shí)sshd會(huì)為登錄后得到的shell程序準(zhǔn)備一個(gè)pty,以支持人機(jī)交互;而第二種方式,在登錄之后并不需要交互,所以sshd就并不會(huì)使用pty,而是直接通過(guò)socket將shell的輸入輸出跟自己連接起來(lái)(再由sshd將其轉(zhuǎn)發(fā)給ssh-client)。下面再說(shuō)一下pty。pty分master和slave兩端,跟pipe的兩端很像,寫(xiě)入到master端的數(shù)據(jù)可以原樣從slave端讀出,反之亦然。在上面所述的第一種方式下,各個(gè)進(jìn)程的聯(lián)系如下:ssh-client <-> [socket] <-> sshd <-> [master] <-> [slave] <-> shellpty的master和slave兩端分別被sshd和shell打開(kāi),就像pipe一樣,將它們的輸入輸出連接起來(lái)。而pty跟pipe的不同之處,則正是前面所說(shuō)的終端的功能(pty的slave端對(duì)于shell來(lái)說(shuō)就是一個(gè)終端)。跟tty不同,tty是系統(tǒng)初始化時(shí)生成的,其數(shù)目是固定的(比如12個(gè))。而pty是系統(tǒng)啟動(dòng)后動(dòng)態(tài)創(chuàng)建的。其創(chuàng)建的方法是:fd = open('/dev/ptms'),這樣就得到了一個(gè)pty。open返回的fd代表master端,通過(guò)ptyname(fd)可以得到對(duì)應(yīng)slave端的文件路徑(比如'/dev/pts/2'),這個(gè)設(shè)備文件是master端被open之后動(dòng)態(tài)生成的。【權(quán)限控制】用戶登錄驗(yàn)證成功后,getty、sshd這樣的程序就會(huì)為用戶啟動(dòng)他所對(duì)應(yīng)的"登錄后執(zhí)行的程序",并且在此之前會(huì)通過(guò)setuid()、setgid()這樣的系統(tǒng)調(diào)用,設(shè)置好進(jìn)程的uid和gid(用戶和組)。之后,這個(gè)進(jìn)程對(duì)文件的讀、寫(xiě)、執(zhí)行,以及對(duì)系統(tǒng)調(diào)用的使用,等都會(huì)受到進(jìn)程uid和gid的限制。用戶對(duì)系統(tǒng)的各種操作都是通過(guò)進(jìn)程來(lái)完成的。而用戶的輸入輸出都被定向到他登錄后所得到的那個(gè)進(jìn)程上,于是用戶能夠控制這個(gè)進(jìn)程,來(lái)干他想干的事情(如果這個(gè)進(jìn)程接受控制的話,比如進(jìn)程運(yùn)行著一個(gè)shell程序)。用戶的操作都受限于進(jìn)程的uid和gid,比如文件訪問(wèn)、向進(jìn)程發(fā)送信號(hào)、使用系統(tǒng)調(diào)用、監(jiān)聽(tīng)網(wǎng)絡(luò)端口、等都需要對(duì)其做檢查。除非是root用戶,否則沒(méi)有權(quán)限使用setuid()、setgid()這樣的系統(tǒng)調(diào)用來(lái)修改進(jìn)程的uid和gid。而login時(shí),login、sshd這樣的進(jìn)程之所以能夠設(shè)置登錄后進(jìn)程的uid和gid,正是因?yàn)樗鼈兌际莚oot用戶的進(jìn)程。如果想要改變登錄用戶,則必須利用屬于root用戶的進(jìn)程。一種辦法是退出登錄,然后走老路,重新跟getty、sshd這樣的進(jìn)程打交道,而使用其他用戶名登錄。另一種辦法是執(zhí)行一個(gè)setuid/setgid程序(參見(jiàn)《記一個(gè)linux內(nèi)核內(nèi)存提權(quán)問(wèn)題》中的說(shuō)明),臨時(shí)獲得root權(quán)限,再實(shí)現(xiàn)用戶的切換(例如su就是這樣一個(gè)能實(shí)現(xiàn)用戶切換的setuid命令)。為了實(shí)現(xiàn)進(jìn)程權(quán)限控制中的各種功能,進(jìn)程的uid和gid其實(shí)并不止一組,主要有如下三組:1、ruid/rgid,代表實(shí)際的用戶和組id;2、euid/egid,代表當(dāng)前生效的用戶和組id;3、suid/sgid,代表保留的用戶和組id;什么意思呢?一般情況下,在用戶登錄得到的進(jìn)程中,這三組id都是相同的值,與登錄用戶相對(duì)應(yīng)(假設(shè)為aaa)。而用戶新創(chuàng)建的進(jìn)程也會(huì)全部繼承這三組id。當(dāng)用戶執(zhí)行一個(gè)setuid/setgid程序時(shí),執(zhí)行程序的進(jìn)程將得到可執(zhí)行程序owner(假設(shè)為bbb)的用戶屬性,euid/egid和suid/sgid會(huì)更新為bbb(而ruid/rgid不會(huì)被更新)。這些id在進(jìn)程操作別的對(duì)象時(shí)(比如寫(xiě)文件、發(fā)信號(hào)、等)或被別的進(jìn)程操作時(shí)(比如其他進(jìn)程向其發(fā)信號(hào)、等)會(huì)被用做校驗(yàn)。ruid/rgid和euid/egid在進(jìn)程被操作的時(shí)候會(huì)使用到,euid/egid在進(jìn)程發(fā)起操作的時(shí)候會(huì)用到。比如有一個(gè)進(jìn)程,其ruid是aaa、euid是bbb,則euid為aaa或bbb的其他進(jìn)程都可以向其發(fā)送信號(hào)。而該進(jìn)程在進(jìn)行讀寫(xiě)文件、創(chuàng)建文件、等操作時(shí),使用的則是用戶bbb的權(quán)限:它創(chuàng)建的文件owner是bbb、它在訪問(wèn)owner是aaa的文件時(shí)以other權(quán)限進(jìn)行校驗(yàn)。那么第三組id,suid/sgid又是干什么用的呢?之前說(shuō)普通用戶沒(méi)有權(quán)限使用setuid()這樣的系統(tǒng)調(diào)用來(lái)改變進(jìn)程的uid和gid,其實(shí)這個(gè)說(shuō)法并不確切。進(jìn)程其實(shí)是有權(quán)限將自己的ruid/rgid、euid/egid、suid/sgid的值修改成與這三者之一相等的值。比如ruid/rgid為aaa、suid/sgid為bbb,則用戶可以任意將euid/egid設(shè)置為aaa或bbb。因?yàn)榇蠖鄶?shù)情況下這三組id是等值的,所以一般說(shuō)用戶進(jìn)程不能修改自己的uid和gid(只能從aaa修改為aaa,相當(dāng)于不能修改)。但是執(zhí)行setuid的程序后,進(jìn)程的這三組id就有了兩種不同的取值,ruid/rgid等于aaa、euid/egid和suid/sgid等于bbb,于是進(jìn)程的uid就有了一定的選擇余地。比如此時(shí)進(jìn)程的euid/egid被更新成了bbb,那就不能再以owner身份去操作aaa的文件了(注意,這個(gè)進(jìn)程原本是以aaa用戶登錄而得到的)。不過(guò)沒(méi)關(guān)系,進(jìn)程是有權(quán)限將euid/egid改回aaa的,因?yàn)閞uid/rgid的值是aaa。但是改回來(lái)之后,ruid/rgid和euid/egid都是aaa了,要再想把euid/egid改為bbb怎么辦呢?suid/sgid就是為此而生的,作為一個(gè)備份,它的值是bbb,這使得euid/egid還能夠修改回bbb。當(dāng)然,進(jìn)程也有權(quán)限將euid/egid和suid/sgid都改回aaa,這將使得它們不再能修改成bbb了。【會(huì)話退出】用戶登錄是一個(gè)會(huì)話的開(kāi)始。登錄之后,用戶會(huì)得到一個(gè)跟用戶使用的終端相連的進(jìn)程,這個(gè)進(jìn)程被稱(chēng)作是這個(gè)會(huì)話的leader,會(huì)話的id就等于該進(jìn)程的pid。由該進(jìn)程fork出來(lái)的子進(jìn)程都是這個(gè)會(huì)話的成員(進(jìn)程的sid等于該會(huì)話id)。leader進(jìn)程的退出,將導(dǎo)致它所連接的終端被hangup,這意味著會(huì)話結(jié)束。反過(guò)來(lái),像ssh這樣的遠(yuǎn)程連接也可以通過(guò)斷開(kāi)連接的方式來(lái)使終端hangup,這將使得leader進(jìn)程收到SIGHUP信號(hào)而退出。如果會(huì)話使用的是pty,其本身是隨會(huì)話的建立而創(chuàng)建出來(lái)的,會(huì)話結(jié)束,則pty被銷(xiāo)毀;而如果會(huì)話使用的是tty,其本身是在系統(tǒng)初始化時(shí)創(chuàng)建的,并不依賴于會(huì)話的建立,則會(huì)話結(jié)束時(shí),tty依然存在。init進(jìn)程檢測(cè)到使用該tty的會(huì)話已經(jīng)結(jié)束,便會(huì)重新啟動(dòng)一個(gè)getty來(lái)監(jiān)聽(tīng)該tty。不過(guò),會(huì)話結(jié)束,并不意味著在該會(huì)話中創(chuàng)建的所有進(jìn)程都結(jié)束了。所謂的daemon進(jìn)程,正是在某個(gè)會(huì)話中創(chuàng)建,但是卻不依賴該會(huì)話,而常駐后臺(tái)的進(jìn)程。具體來(lái)說(shuō),當(dāng)終端hangup時(shí),內(nèi)核會(huì)有如下兩個(gè)動(dòng)作:1、向?qū)?yīng)會(huì)話的leader進(jìn)程發(fā)送SIGHUP信號(hào)。而一般來(lái)說(shuō),會(huì)話的leader進(jìn)程很可能是一個(gè)shell,它在收到SIGHUP信號(hào)后,并不是馬上退出,而是會(huì)向它所啟動(dòng)的子進(jìn)程都各自發(fā)送一個(gè)SIGHUP信號(hào),將它們都?xì)⑺溃缓笞约翰磐顺觥2贿^(guò),如果是這個(gè)作為leader進(jìn)程shell自己退出,而導(dǎo)致終端hangup的話,向其子進(jìn)程發(fā)送SIGHUP信號(hào)的事情就不會(huì)發(fā)生了,因?yàn)閟hell退出在先,它再也不會(huì)收到SIGHUP信號(hào);2、修改所有打開(kāi)該終端的文件句柄,改成一個(gè)不可讀不可寫(xiě)的實(shí)現(xiàn);所以,在會(huì)話退出之后還常駐后臺(tái)的進(jìn)程肯定是沒(méi)法跟終端交互的。而要想讓進(jìn)程常駐后臺(tái),一般有如下幾種方法:1、避免shell發(fā)SIGHUP信號(hào);主要有兩種辦法:1)主動(dòng)exit,而不是直接斷開(kāi)終端;2)兩次fork。因?yàn)閟hell只認(rèn)識(shí)它自己fork出來(lái)的子進(jìn)程,并不知道"子又生孫"的事情,也就不會(huì)給孫子進(jìn)程發(fā)送SIGHUP信號(hào)了;2、忽略SIGHUP信號(hào);終端hangup時(shí)進(jìn)程可能收到shell發(fā)送的SIGHUP信號(hào)。信號(hào)的默認(rèn)處理動(dòng)作是退出進(jìn)程,但是該信號(hào)是可以忽略的。忽略信號(hào),就可以使得后臺(tái)進(jìn)程不會(huì)隨會(huì)話退出而退出。nohup命令就是做這件事情的,而且它做得更完整一些,不僅忽略SIGHUP,還會(huì)將進(jìn)程的標(biāo)準(zhǔn)輸入重定向?yàn)?dev/null、輸出重定向到nohup.out文件;3、使用setsid()系統(tǒng)調(diào)用,為進(jìn)程開(kāi)啟一個(gè)新的會(huì)話;從一個(gè)會(huì)話中fork出來(lái)的進(jìn)程,默認(rèn)都是屬于這個(gè)會(huì)話的。但是進(jìn)程可以調(diào)用setsid(),使自己脫離原先的會(huì)話,而成為一個(gè)新會(huì)話的leader。于是,原先的會(huì)話退出,就不會(huì)影響到新建的會(huì)話了。setsid命令包裝了setsid()系統(tǒng)調(diào)用,可以為進(jìn)程創(chuàng)建新的會(huì)話。不過(guò)它并不對(duì)新進(jìn)程的輸入輸出進(jìn)行重定向,這就意味著新進(jìn)程的輸入輸出還是連接到原先的那個(gè)tty的,這可能跟原先的會(huì)話爭(zhēng)搶輸入。所以,對(duì)新會(huì)話的進(jìn)程進(jìn)行輸入輸出的重定向也是一件很重要的事情。一個(gè)進(jìn)程成為daemon進(jìn)程,可以不隨會(huì)話的退出而退出,但是進(jìn)程的uid/gid并不會(huì)因此而改變。對(duì)應(yīng)的用戶還可以在其他會(huì)話中,通過(guò)發(fā)信號(hào)等方式,操作那些原來(lái)由他所啟動(dòng)的daemon進(jìn)程(因?yàn)闄?quán)限控制是以用戶為準(zhǔn)的,而并不考慮會(huì)話)。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 锦屏县| 昌吉市| 苍溪县| 达尔| 汉寿县| 汕头市| 宜阳县| 商水县| 醴陵市| 台湾省| 固原市| 洛川县| 宝坻区| 合水县| 贵德县| 伊宁县| 赣州市| 三江| 电白县| 中阳县| 开原市| 腾冲县| 光山县| 云安县| 长岭县| 扎鲁特旗| 丰城市| 大冶市| 平度市| 天台县| 房产| 项城市| 尚义县| 定安县| 安吉县| 长顺县| 筠连县| 马龙县| 陇西县| 登封市| 招远市|