版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第15章
其他LinuxShell種類介紹15.1CShell15.1.1csh簡(jiǎn)介CShell(簡(jiǎn)稱csh)是由BillJoy在1979年開發(fā)的。他開發(fā)CShell的主要意圖是想創(chuàng)建一個(gè)具有C語言類似語法的Shell。從BSDUnix系統(tǒng)的2BSD版本發(fā)布時(shí)開始,CShell就已經(jīng)廣泛發(fā)布了。CShell是一個(gè)通常運(yùn)行在文本窗口并允許用戶輸入命令的命令處理程序。CShell也同樣可以從腳本文件中讀取命令。與其它LinuxShell類似,它支持文件名統(tǒng)配、管道、heredocuments、命令替換、變量和用于條件測(cè)試和循環(huán)的控制結(jié)構(gòu)。CShell與其它Shell的不同之處在于它的交互式特性和總體風(fēng)格。它的新特性使它使用起來更簡(jiǎn)單快速。CShell的總體風(fēng)格看起來更像C語言并且看起來可讀性更好。15.1.1csh簡(jiǎn)介在很多系統(tǒng)中(例如,MacOSX和RedHatLinux),csh實(shí)際上是tcsh,tcsh是csh的改進(jìn)版。在這些系統(tǒng)中,csh和tcsh都鏈接到包含tcsh可執(zhí)行程序的同一個(gè)文件,所以它們都調(diào)用同一個(gè)CShell的改進(jìn)版。而在Debian、Ubuntu以及它們的衍生版本中,csh和tcsh是兩個(gè)不同的包。前者是基于原始BSD版本的csh,而后者是改進(jìn)的tcsh。tcsh增添了文件名和命令補(bǔ)全功能,以及從Tenex系統(tǒng)借鑒來的命令行編輯概念(這便是tcsh中‘t’的由來)。因?yàn)閠csh只是增添功能而并沒有做更改,所有tcsh是向前兼容CShell的。盡管tcsh一開始是Joy創(chuàng)建的原始代碼數(shù)的側(cè)枝,但現(xiàn)在它已經(jīng)是用于持續(xù)開發(fā)的主要分支了。tcsh是很穩(wěn)定的,基本上是每年發(fā)布一個(gè)新版本,而大部分都是小的漏洞修復(fù)。15.1.2csh的特性CShell的主要設(shè)計(jì)目標(biāo)是使它看起來更像C語言,并更好地用于交互式使用。我們知道Unix(以及Linux和類Unix)系統(tǒng)幾乎完全由C語言寫成,所以CShell作為命令語言的首要目標(biāo)就是在文體上盡量與系統(tǒng)其它部分保持一致。CShell的關(guān)鍵字、使用的圓括號(hào)、內(nèi)部表達(dá)式語法和對(duì)數(shù)組的支持都是受C語言強(qiáng)烈的影響。按照今天的標(biāo)準(zhǔn),相比很多其它流行的腳本語言,csh可能并不特別像C語言。但當(dāng)它與BourneShell(sh)相比時(shí),它們間的不同就特別明顯。下面這個(gè)例子說明了CShell的常用的表達(dá)式操作符和語法。15.1.2csh的特性#!/bin/csh
if($days>365)then
echoThisisoverayear.
endif如果使用BourneShell其語法將類似如下所示:#!/bin/sh
if[$days-gt365]then
echoThisisoverayear.
fi15.1.2csh的特性BourneShell缺少一個(gè)表達(dá)式語法。方括號(hào)條件需要由運(yùn)行較慢的外部程序test來計(jì)算。BourneShell的if命令把它的參數(shù)當(dāng)做需要作為子進(jìn)程運(yùn)行的新命令處理,如果子進(jìn)程以返回碼0退出,BourneShell將查找then從句并運(yùn)行其嵌套的塊。否則,它將運(yùn)行else代碼塊。相比之下,csh可以直接計(jì)算表達(dá)式,這使它更快速。它同樣還聲稱有更好的可讀性:它的表達(dá)式使用的語法和操作符大部分是從C語言復(fù)制的。CShell的第二個(gè)目標(biāo)是更好地用于交互式使用。它引入了很多使它更簡(jiǎn)單快速的新特性,以及更友好地在終端打印命令使用。這些特性中的最要的是歷史記錄、編輯機(jī)制、別名、目錄堆棧、波浪號(hào)、cdpath、作業(yè)控制和路徑散列法。15.1.2csh的特性歷史記錄:內(nèi)部命令history允許用戶重調(diào)用先前的命令,并通過幾個(gè)按鍵就可以返回它們。例如,將兩個(gè)感嘆號(hào)“!!”作為命令輸入,就會(huì)使前一個(gè)命令馬上運(yùn)行。還有其它簡(jiǎn)短的按鍵組合,例如,“!$”表示前一個(gè)命令最后一個(gè)參數(shù)。編輯操作符:編輯不僅可以在前一個(gè)命令的文本中完成,同樣可以在變量替換時(shí)。操作符從單個(gè)字符串搜索/替換變化,到解析路徑名,到擴(kuò)展指定的段。別名:內(nèi)部命令alias允許用戶定義別名,當(dāng)用戶輸入一個(gè)別名時(shí),CShell將在內(nèi)部將其解釋為用戶先前定義的內(nèi)容。對(duì)于很多簡(jiǎn)單的情況,別名執(zhí)行的更快速,并且比腳本更方便。目錄堆棧:目錄堆棧允許用戶放入和取出當(dāng)前的工作目錄,使在文件系統(tǒng)中的不同地方之間前后跳轉(zhuǎn)更方便。波浪號(hào):它使用字符‘~’為home目錄提供了一個(gè)速記方法。cdpath:它將搜索路徑的概念擴(kuò)展到了cd命令:如果指定的目錄不在當(dāng)前目錄,csh將嘗試在cdpath目錄中找到它。作業(yè)控制:在80年代時(shí),大部分用戶只有字符模式的終端,所以他們同時(shí)只能工作在一個(gè)任務(wù)上。CShell的作業(yè)控制允許用戶通過輸出“CTRL-Z”來掛起當(dāng)前活躍的任務(wù),并創(chuàng)建一個(gè)CShell新任務(wù)。用戶可以使用fg命令在任務(wù)之間前后切換?;钴S的任務(wù)表示是放在前臺(tái)的任務(wù)。其它的任務(wù)要么被認(rèn)為是掛起的或是運(yùn)行在后臺(tái)的。路徑散列法:路徑散列法加速了CShell搜索可執(zhí)行文件的速度。CShell會(huì)查閱一個(gè)通過掃描path的所有目錄構(gòu)建的哈希表。這個(gè)表通??梢愿嬖VCShell在哪可以找到文件(如果它存在)而不需要在所有目錄中查找。這個(gè)表可以使用“rehash”命令來更新。15.1.3csh的內(nèi)部變量CShell中的某些變量控制著的行為,并且這些變量中有些不需要賦值(即,可以使用set命令簡(jiǎn)單地設(shè)置變量名自身而不要指定任何值)。unset命令可以用于消除任何不需要的變量。下面,就讓我們來了解幾個(gè)常用的csh內(nèi)建變量。15.1.3csh的內(nèi)部變量argv–用于Shell腳本中存放參數(shù)值的特殊變量。autologout–包含Shell自動(dòng)退出前Shell可以處于空閑狀態(tài)的分鐘數(shù)。history–設(shè)置可以存放多少歷史(先前運(yùn)行的命令)行。ignoreeof–阻止使用CTRL-d退出。noclobber–使用重定向時(shí)阻止文件的覆蓋。path–包含當(dāng)運(yùn)行程序或Shell腳本時(shí)需要搜索的目錄列表。prompt–設(shè)置命令行提示符字符串。term–包含當(dāng)前終端的類型。15.1.3csh的內(nèi)部變量在CShell中使用內(nèi)建命令set來定義一個(gè)變量。CShell既支持常規(guī)的變量也支持?jǐn)?shù)組變量。例如如下所示:setautologout=5
#設(shè)置一個(gè)數(shù)組變量varsetvar=(abc)15.1.4csh的內(nèi)部命令和其他Shell的內(nèi)部命令一樣,CShell的內(nèi)部命令就是在Shell內(nèi)部運(yùn)行的命令。如果一個(gè)內(nèi)部命令作為管道的任意部分出現(xiàn)(除了是管道的最后一條命令外),則這個(gè)內(nèi)部命令將運(yùn)行在子Shell中。如果你從CShell命令行提示符中輸入命令,則系統(tǒng)首先搜索內(nèi)部命令,若內(nèi)部命令不存在,則系統(tǒng)會(huì)搜索由path變量指定的目錄。有些CShell內(nèi)部命令和操作系統(tǒng)命令具有同樣的名稱。然而,這些命令不必以同樣的方式運(yùn)作。關(guān)于命令如何工作的更多信息,可以查看相應(yīng)的命令描述。如果你在Shell中運(yùn)行Shell腳本,并且Shell腳本的第一行以#!/ShellPathname開頭,比如CShell就將運(yùn)行注釋中指定的Shell來處理腳本。否則,它將運(yùn)行默認(rèn)的Shell。如果由默認(rèn)的Shell運(yùn)行,CShell的內(nèi)部命令可能將不會(huì)被識(shí)別。所以運(yùn)行CShell命令時(shí),要使腳本的第一行為#!/bin/csh。15.1.4csh的內(nèi)部命令下面我們就來了解學(xué)習(xí)一下CShell的內(nèi)部命令。@命令,其語法類似如下所示:@
[Name[n]
=
Expression]當(dāng)不指定參數(shù)時(shí),@命令會(huì)顯示所有Shell變量的值。否則,將把Name變量的值設(shè)置為表達(dá)式Expression的值。如果表達(dá)式中包含<、>、&或|字符,那么這部分表達(dá)式必須被放在圓括號(hào)中。當(dāng)語法中的n指定時(shí),Name數(shù)組變量的第n個(gè)元素將被設(shè)置為表達(dá)式Expression的值。而且,Name數(shù)組變量和它的第n個(gè)元素必須已經(jīng)存在。15.1.4csh的內(nèi)部命令alias命令,其語法類似如下所示:alias[Name[WordList]]如果不指定任何參數(shù),alias命令將顯示所有別名。否則,命令顯示指定Name的別名。如果WordList被指定,則這個(gè)命令將把WordList的值指定給Name。指定的別名Name不能被alias或unalias。bg命令,其語法類似如下所示:bg[%Job…]此命令用于將當(dāng)前任務(wù)或由%Job指定的任務(wù)放到后臺(tái)執(zhí)行,恢復(fù)運(yùn)行處于停止?fàn)顟B(tài)的任務(wù)。break命令,用于終止foreach或while循環(huán),繼續(xù)運(yùn)行這些循環(huán)之后的命令。breaksw命令,用于終止switch命令,繼續(xù)運(yùn)行endsw命令之后的命令。15.1.4csh的內(nèi)部命令case命令,其語法如下所示:caseLabel:此命令用于在switch命令中定義一個(gè)Label。cd命令,其語法類似如下所示:cd[Name]等同于chdir命令(見下面的描述)。chdir命令,其語法類似如下所示:chdir[Name]變更當(dāng)前的目錄到由Name指定的目錄。如果沒有指定Name,此命令會(huì)將當(dāng)前目錄切換到你的home目錄。如果指定Name不是當(dāng)前目錄的子目錄,并且其路徑不是以/,./或../開頭,Shell將會(huì)檢查Shell變量cdpath的每一部分,看是否有子目錄匹配Name。如果Name的內(nèi)容是以/開頭的,那么Shell將嘗試看它是否為一個(gè)目錄。15.1.4csh的內(nèi)部命令continue命令,此命令用于跳過while或foreach的當(dāng)前循環(huán),直接繼續(xù)執(zhí)行它們的下一次循環(huán)。default:命令,標(biāo)識(shí)switch語句的默認(rèn)情況。它出現(xiàn)在所有其它c(diǎn)ase語句之后。dirs命令,用于顯示目錄堆棧。echo命令,寫字符串到Shell的標(biāo)準(zhǔn)輸出。else命令,當(dāng)使用語句if(expr)then..else…enif時(shí),else語句是csh的內(nèi)部命令。如果(expr)為真,else語句之前的命令被執(zhí)行。如果(expr)為假,則在else和endif語句之間的命令被執(zhí)行。end命令,此命令用于表示foreach命令的結(jié)束。foreach和end語句必須放在分隔的兩行。endif命令,此命令用于表示if語句的結(jié)束。endsw命令,此命令用于表示switch語句的結(jié)束。15.1.4csh的內(nèi)部命令eval命令,此命令的語法如下所示:evalParameter…將參數(shù)Parameter作為Shell的輸入,并執(zhí)行當(dāng)前Shell上下文產(chǎn)生的命令。它通常用于執(zhí)行作為命令替換或變量替換的結(jié)果產(chǎn)生的命令,因?yàn)榻馕霭l(fā)生在這些替換之前。exec命令,其命令的語法類似如下所示:execCommand此命令用于運(yùn)行指定的命令代替運(yùn)行當(dāng)前Shell。exit命令,此命令的語法類似如下所示:exit(Expression)以Shell變量status的值退出Shell,或是以指定表達(dá)式Expression的值退出Shell。15.1.4csh的內(nèi)部命令fg命令,其命令的語法類似如下所示:fg[%Job…]把當(dāng)前任務(wù)或有%Job指定的任務(wù)放在前臺(tái)執(zhí)行,繼續(xù)運(yùn)行處于停止?fàn)顟B(tài)的任務(wù)。foreach命令,其命令的語法類似如下所示:foreachName(List)Command…此命令用于連續(xù)地把每List中每一個(gè)元素的值賦值給Name變量,并執(zhí)行foreach與end命令之間的一系列命令。glob命令,其命令的語法類似如下所示:globList此命令與echo命令類似。15.1.4csh的內(nèi)部命令history命令,其命令的語法類似如下所示:history[-r|-h][n]顯示歷史記錄列表。舊的記錄將被先顯示。如果你指定了數(shù)量n,只有指定的最新n條記錄被顯示。-r選項(xiàng)表示倒序,所以在執(zhí)行-r選項(xiàng)的情況下,最新的記錄將被首先顯示。-h選項(xiàng)表示顯示記錄時(shí)不顯示編號(hào)。jobs命令,其命令的語法類似如下所示:jobs[-l]此命令用于列出活躍的任務(wù)。使用-l選項(xiàng),除了列出任務(wù)編號(hào)和名稱外,jobs命令還將列出進(jìn)程ID。kill命令,其命令的語法類似如下所示:kill-l|[[-Signal]%
Job...|PID...]發(fā)送TERM(終結(jié))信號(hào)或由Signal指定的信號(hào)到指定的任務(wù)或進(jìn)程。-l選項(xiàng),指示列出信號(hào)的名稱。15.1.4csh的內(nèi)部命令limit命令,其命令的語法類似如下所示:limit[-h][Resource
[Max-Use]]限制當(dāng)前進(jìn)程的指定資源的使用。進(jìn)程資源限制定義在文件/etc/security/limits文件中??煽刂频馁Y源是CPU時(shí)間、文件大小、數(shù)據(jù)大小、coredump大小和內(nèi)存的使用。logout命令,此命令用于注銷登錄Shell。nice命令,其命令的語法類似如下所示:nice[+n][command]如果沒有指定數(shù)值,運(yùn)行在這個(gè)Shell中的命令的優(yōu)先級(jí)將被設(shè)為24。如果指定了+n,則優(yōu)先級(jí)會(huì)加上指定的數(shù)值。如果+n和command都被指定,那么命令就會(huì)以24加上指定的數(shù)值為優(yōu)先級(jí)運(yùn)行。如果你有root用戶權(quán)限,你可以運(yùn)行nice命令時(shí)指定一個(gè)負(fù)值。rehash命令,此命令用于引起Shell變量path中的目錄內(nèi)容哈希表的重計(jì)算。只有當(dāng)用戶添加了一個(gè)命令到path變量中的自己的目錄中或某人修改了的一個(gè)path變量中的系統(tǒng)目錄的內(nèi)容時(shí),才需要運(yùn)行rehash命令。15.1.4csh的內(nèi)部命令set命令,其命令的語法如下所示:set[[Name[n]][=Word]]|[Name=(List)]當(dāng)沒有參數(shù)指定時(shí),set命令會(huì)顯示所有變量的值。如果僅指定了變量名Name,CShell將把變量Name的值設(shè)為空字符串。setenv命令,其命令的語法如下所示:setenvNameValue此命令用于將由Name指定的環(huán)境變量的值設(shè)置Value。shift命令,其命令的語法如下所示:shift[Variable]此命令用于將Shell變量argv中的元素向左移。如果Shell變量argv或指定的變量沒有設(shè)置或其值少于一個(gè)單詞則會(huì)產(chǎn)生一個(gè)錯(cuò)誤。15.1.4csh的內(nèi)部命令source命令,其命令的語法類似如下所示:source[-h]Name讀取并執(zhí)行名稱為Name的文件中的命令。這些命令不會(huì)被存放在歷史記錄列表中。如果使用-h選項(xiàng),則把讀取的命令存入歷史列表中而不執(zhí)行。stop命令,其命令的語法如下所示:stop[%Job...]此命令用于停止當(dāng)前任務(wù)或運(yùn)行在后臺(tái)的指定任務(wù)。time命令,其命令的語法如下所示:time[Command]此命令用于控制命令的自動(dòng)計(jì)時(shí)。如果不指定Command,time命令會(huì)顯示當(dāng)前Shell及其子Shell使用的時(shí)間概況。如果指定Command,則命令的運(yùn)行時(shí)間將被計(jì)時(shí),命令執(zhí)行完成后,Shell會(huì)顯示用時(shí)的概況。15.1.4csh的內(nèi)部命令umask命令,其命令的語法如下所示:umask[Value]此命令用于確定文件權(quán)限。指定的值Value用于確定文件創(chuàng)建時(shí)的權(quán)限。默認(rèn)值是022。如果不指定Value,則顯示當(dāng)前設(shè)置的值。unalias命令,其命令的語法如下所示:unalias*|Pattern此命令用于移除指定的別名。如果指定*,則移除所有的別名。unalias一個(gè)不存在的別名不會(huì)產(chǎn)生錯(cuò)誤。unlimit命令,其命令的語法如下所示:unlimit
[-h][Resource]此命令用于移除指定資源的限制。如果沒有資源Resource指定,則取消所有資源的限制。unset命令,其命令的語法如下所示:unset*|Pattern此命令用于刪除指定的變量。如果指定*,則刪除所有定義的變量。如果指定的變量沒有設(shè)置,不會(huì)產(chǎn)生一個(gè)錯(cuò)誤。15.1.4csh的內(nèi)部命令while命令,其命令的語法如下所示:while(Expression)
Command.
.
.
end此命令用于當(dāng)表達(dá)式Expression的值為非0時(shí),執(zhí)行while和end語句之間的所有命令。你可以使用break命令結(jié)束while循環(huán),或使用continue命令跳過本次循環(huán)而直接執(zhí)行下一次循環(huán)。while和end語句必須在單獨(dú)放在分隔的兩行。15.1.5tcsh在csh基礎(chǔ)上的新特性這一節(jié)我們主要介紹一下tcsh在csh基礎(chǔ)上的主要增強(qiáng)功能。它們包括:命令行編輯器、編輯指令、補(bǔ)全和列表、拼寫校正、目錄堆棧替換、自動(dòng),定期和定時(shí)事件、本地語言系統(tǒng)支持、終端管理和新增的變量。關(guān)于命令行編輯器功能:命令行輸入可以使用類似于在GNUEmacs或vi中使用的擊鍵序列來編輯。編輯器只有當(dāng)CShell變量edit被設(shè)置時(shí)才生效,在交互式CShell中此變量默認(rèn)是設(shè)置的。內(nèi)部命令bindkey可以顯示和更改鍵綁定。Emacs風(fēng)格鍵綁定被默認(rèn)使用,但bindkey命令可以更改鍵綁定為vi風(fēng)格。15.1.5tcsh在csh基礎(chǔ)上的新特性這一節(jié)我們主要介紹一下tcsh在csh基礎(chǔ)上的主要增強(qiáng)功能。它們包括:命令行編輯器、編輯指令、補(bǔ)全和列表、拼寫校正、目錄堆棧替換、自動(dòng),定期和定時(shí)事件、本地語言系統(tǒng)支持、終端管理和新增的變量。關(guān)于命令行編輯器功能:命令行輸入可以使用類似于在GNUEmacs或vi中使用的擊鍵序列來編輯。編輯器只有當(dāng)CShell變量edit被設(shè)置時(shí)才生效,在交互式CShell中此變量默認(rèn)是設(shè)置的。內(nèi)部命令bindkey可以顯示和更改鍵綁定。Emacs風(fēng)格鍵綁定被默認(rèn)使用,但bindkey命令可以更改鍵綁定為vi風(fēng)格。15.1.5tcsh在csh基礎(chǔ)上的新特性關(guān)于補(bǔ)全和列表功能:tcsh可以讓用戶只輸入單詞的一部分(例如ls/usr/lo)并點(diǎn)擊Tab鍵來運(yùn)行complete-word編輯器命令,這時(shí)tcsh就會(huì)在輸入緩沖區(qū)中使用完整的單詞替換不完整的單詞來補(bǔ)全文件名(變?yōu)閘s/usr/local/)。如果沒有找到匹配的內(nèi)容,終端響鈴就會(huì)想起。如果單詞已經(jīng)補(bǔ)全,那么字符‘/’(或空格)就會(huì)被添加到單詞的結(jié)尾。命令或變量的補(bǔ)全方式大致相同。例如,輸入hostn[Tab],如果hostname是你系統(tǒng)中以hostn開頭的唯一命令時(shí),那么tcsh會(huì)將hostn補(bǔ)全為hostname。命令補(bǔ)全功能可以在path變量定義的所有目錄中查找命令。輸入echo$SHE[Tab],如果再?zèng)]有其它變量以SHE開頭,那么$SHE會(huì)被補(bǔ)全為$SHELL。15.1.5tcsh在csh基礎(chǔ)上的新特性tcsh會(huì)通過解析輸入緩沖區(qū)來確定你想補(bǔ)全的單詞是否應(yīng)該當(dāng)做文件名、命令或變量來補(bǔ)全。緩沖區(qū)中的第一個(gè)單詞和后跟字符‘;’、‘|’、‘|&’、‘&&’或‘||’的第一個(gè)單詞被解析為一個(gè)命令。一個(gè)以字符‘$’開頭的單詞被解析為變量。其它的則被解析為文件名。你可以隨時(shí)通過輸入‘^D’(Ctrl+D)來運(yùn)行delete-char-or-list-or-eof編輯器命令以列出所有可能的單詞補(bǔ)全。如果設(shè)置了Shell變量autolist,每當(dāng)補(bǔ)全失敗時(shí),tcsh都會(huì)列出剩下的選擇15.1.5tcsh在csh基礎(chǔ)上的新特性關(guān)于拼寫校正功能:tcsh可以糾正文件名、命令或變量名的拼寫。單個(gè)單詞可以使用spell-word編輯器命令來拼寫校正,而整個(gè)輸入緩沖區(qū)可以使用spell-line編輯器命令。Shell變量correct可以被設(shè)置為“cmd”用來校正命令名,或“all”用來校正每次輸入回車后的整行,并且可以設(shè)置變量autocorrect,使在每次嘗試補(bǔ)全之前校正被補(bǔ)全的單詞。當(dāng)拼寫校正以這些方法中的任何一種被調(diào)用,并且tcsh認(rèn)為命令行的任何部分存在拼寫錯(cuò)誤時(shí),它會(huì)提示正確的行。15.1.5tcsh在csh基礎(chǔ)上的新特性關(guān)于目錄堆棧替換:目錄堆棧是一個(gè)目錄的列表,從0開始編號(hào),被內(nèi)部命令pushd、popd和dirs所使用。命令dirs可以用于打印、存儲(chǔ)、恢復(fù)和清除目錄堆棧。Shell變量savedirs和dirsfile可以設(shè)置用于在注銷時(shí)自動(dòng)存儲(chǔ)目錄堆棧,而在登錄是自動(dòng)恢復(fù)它。Shell變量dirstack可以用于查看目錄堆棧和將任意目錄放入目錄堆棧。字符‘=’后跟一個(gè)或多個(gè)數(shù)字被擴(kuò)展為一個(gè)目錄堆棧中的條目。特殊情況“=-”則被擴(kuò)展為堆棧中的最后一個(gè)目錄。15.1.5tcsh在csh基礎(chǔ)上的新特性關(guān)于tcsh的自動(dòng)、定期和定時(shí)事件:在Shell的生命周期的不同時(shí)期有多種方式自動(dòng)地運(yùn)行命令和采取其它行動(dòng)。我們這里做了一下總結(jié),詳細(xì)的描述請(qǐng)參考tcsh的man手冊(cè)。內(nèi)部命令sched用于把命令存入預(yù)訂事件列表中,以便在給定的時(shí)間由Shell執(zhí)行。特殊的別名beepcmd、cwdcmd、periodic、precmd、postcmd和jobcmd可以被設(shè)置分別用于當(dāng)Shell響鈴時(shí)、或當(dāng)工作目錄變更時(shí)、或每個(gè)定期時(shí)間時(shí)、或在每次提示符打印之前、或在每個(gè)命令執(zhí)行之前、或當(dāng)每個(gè)命令變更狀態(tài)時(shí)執(zhí)行一些命令。15.1.5tcsh在csh基礎(chǔ)上的新特性Shell變量autologout可以設(shè)置用于在給定的空閑分鐘數(shù)后注銷或鎖住Shell。Shell變量mail可以設(shè)置用于定期地檢查新郵件。Shell變量rmstar可以設(shè)置用于當(dāng)用戶輸入“rm*”命令時(shí),詢問用戶是否真地要執(zhí)行刪除所有文件的操作。Shell變量time可以設(shè)置用于當(dāng)任意命令執(zhí)行的時(shí)間超過指定的CPU秒數(shù)時(shí)自動(dòng)執(zhí)行內(nèi)部命令time。15.1.5tcsh在csh基礎(chǔ)上的新特性關(guān)于tcsh的終端管理:tcsh使用三種不同的終端模式:編輯、引用和執(zhí)行。編輯模式在編輯時(shí)使用,引用模式在引用文字字符時(shí)使用,執(zhí)行模式在執(zhí)行命令時(shí)使用。tcsh在每個(gè)模式常量中保存了一些設(shè)置,所以在困惑狀態(tài)下離開tty(終端)的命令不會(huì)干擾Shell。保存在常量中的終端模式的列表可以使用tcsh的內(nèi)部命令setty來檢查和修改。其內(nèi)部命令echotc、settc和telltc可以用于從命令行操作和調(diào)試終端功能。在支持SIGWINCH或SIGWINDOW的系統(tǒng),tcsh會(huì)自動(dòng)適應(yīng)窗口大小的調(diào)整并校正環(huán)境變量LINES和COLUMNS(如果設(shè)置的話)。15.2KornShell15.2.1ksh簡(jiǎn)介KornShell簡(jiǎn)稱為ksh,它是由DavidKorn于1980年代初期在貝爾實(shí)驗(yàn)室開發(fā)的,并于1983年7月14日在由高級(jí)計(jì)算機(jī)系統(tǒng)協(xié)會(huì)(USENIX)贊助的USENIX年度技術(shù)大會(huì)上宣布。其它早期的貢獻(xiàn)者是貝爾實(shí)驗(yàn)室的開發(fā)人員MikeVeach和PatSullivan,他們分別編寫了Emacs風(fēng)格和vi風(fēng)格的行編輯模式的代碼。直到2000年,ksh還仍是AT&T的專有軟件。從那以后它就是開源軟件了,自2005年年初的93q版本開始,它就已經(jīng)在通用公共許可證(CPL)之下了。ksh是AT&T軟件技術(shù)的開源軟件集合的一部分。由于ksh最初只有通過AT&T的專有許可才可以用,所以有一些免費(fèi)和開源的替代方案在當(dāng)時(shí)被創(chuàng)建,它們包括無版權(quán)的版本,如,pdksh、mksh和zsh。15.2.1ksh簡(jiǎn)介最初的ksh(ksh88)的功能被作為POSIX.2(Shell和實(shí)用程序)標(biāo)準(zhǔn)中命令解釋器的基礎(chǔ)。一些廠商仍然發(fā)布基于舊的ksh88的他們自己的版本,有的是一些擴(kuò)展。ksh93仍由它的作者維護(hù),ksh93的版本命名是通過在它的名字中追加字母,當(dāng)前的版本是ksh93u,它的前一個(gè)版本是ksh93t+,一些中間的漏洞修復(fù)版本的發(fā)布并沒有更改這個(gè)版本字符串。15.2.1ksh簡(jiǎn)介下面是ksh的幾種變體的簡(jiǎn)介:dtksh:ksh93的分支,它是通用桌面環(huán)境(CDE)的一部分。tksh:ksh93的分機(jī),它提供Tk部件工具箱的訪問。oksh:它是OpenBSD的ksh產(chǎn)品的分支。它僅支持GNU/Linux,它被作為DeLiLinux中的默認(rèn)Shell。mksh:是來自MirOSBSD的ksh的免費(fèi)實(shí)現(xiàn)。15.2.2ksh的特性需要特別說明的是,本節(jié)所講述的ksh的特性是基于ksh的1988版本。若要查看你所使用的ksh的版本,請(qǐng)先在ksh的命令行下執(zhí)行如下命令:$set-oemacs然后依次按下按鍵“Esc-Ctrl-V”,你將看到類似如下的信息:$set-oemacs$VersionM-11/16/88i或輸入命令:$set-ovi然后先按一下“Esc”進(jìn)入控制模式,然后再按下按鍵“Ctrl-V”,你同樣會(huì)看到版本信息:$set-ovi$VersionM-11/16/88i15.2.2ksh的特性ksh向后兼容BourneShell并包含了很多CShell的特性,還加入了很多它自己的新特性,其靈感主要來自于貝爾實(shí)驗(yàn)室用戶的需求。由此在與系統(tǒng)交互和編程方面ksh都可以大大地提高你的工作效率和質(zhì)量。ksh程序編寫簡(jiǎn)單,并且比由其它低級(jí)語言(比如C語言)編寫的程序更簡(jiǎn)明和可讀。與其它種類的Shell類似,當(dāng)你準(zhǔn)備編寫并運(yùn)行一些ksh腳本時(shí),但你的登錄Shell又沒有配置為ksh,這時(shí)你就要確保將下面的一行代碼添加到你的ksh腳本的第一行,以保證它會(huì)被ksh執(zhí)行:#!/bin/ksh15.2.2ksh的特性ksh從CShell中引入的新特性包括如下所示:作業(yè)控制:ksh的作業(yè)控制功能實(shí)際上與csh的一樣。程序可以被停止、重新開始、移到后臺(tái)和從后臺(tái)移出。程序可以被使用它們的作業(yè)號(hào)殺掉。別名:程序和ksh腳本連同它們的選項(xiàng)可以另外命令為單個(gè)名稱。函數(shù):類似于其它程序語言,通過允許代碼組織到更小更易管理的單元中,增加了可編程性。函數(shù)同樣允許ksh程序存儲(chǔ)在內(nèi)存中。命令歷史:執(zhí)行過的命令被存儲(chǔ)在歷史文件中,它可以稍后被修改并重新執(zhí)行,或就按照原來的內(nèi)容執(zhí)行??梢员4娑鄠€(gè)登錄會(huì)話的命令,直到達(dá)到用戶指定的限制為止。ksh自身與BourneShell相比的主要新特性包括:命令行編輯:命令可以在vi、emacs或gmacs模式下被編輯,而不必回退或重輸入。15.2.2ksh的特性集成編程特性:一些外部的Linux(Unix或類Unix)命令的功能,包括test、expr、getopt和echo,已經(jīng)集成到了ksh自身中,使常見的編程任務(wù)能以更清潔的方式完成,而不需要?jiǎng)?chuàng)建額外的進(jìn)程??刂平Y(jié)構(gòu):特別是select結(jié)構(gòu),使菜單的創(chuàng)建變得簡(jiǎn)單。調(diào)試功能:我可以使用此功能編寫幫助程序調(diào)試它們的Shell代碼的工具。正則表達(dá)式:具有更好的變量擴(kuò)展中的正則表達(dá)式支持,而且添加了文件名通配符。增強(qiáng)的I/O工具:文件描述符和流可以被指定。多個(gè)文件可以被同時(shí)打開并讀取。新的選項(xiàng)和變量:這些添加提供了更多的環(huán)境定制的控制。提高了性能:使用ksh編寫的程序可以比由BourneShell或csh編寫的類似程序運(yùn)行的更快。安全特性:幫助防止特洛伊木馬和其它類型的入侵嘗試。15.2.2ksh的特性關(guān)于命令行編輯功能:有兩種方法可以進(jìn)入命令行編輯模式。第一種方法是你可以使用環(huán)境變量VISUAL來設(shè)置你的編輯模式。ksh會(huì)檢查這個(gè)變量的值是否以vi或macs(GNUEmacs通常被安裝為gmacs或gnumacs)。設(shè)置環(huán)境變量VISUAL的一個(gè)非常好的方式是把類似如下的一行放入你的主目錄下的.profile或其它環(huán)境文件中:VISUAL=$(whenceemacs)或VISUAL=$(whencevi)內(nèi)部命令whence用于將另一個(gè)命令的名稱作為它的參數(shù),然后輸出那個(gè)命令的全路徑到標(biāo)準(zhǔn)輸出。在這里使用這個(gè)命令是使上述語句具有較好的可移植性,因?yàn)槠渌到y(tǒng)的編輯器可能存儲(chǔ)在不同的目錄下。15.2.2ksh的特性進(jìn)入命令行編輯模式的第二種方法是使用“set-o”命令,就是我們?cè)诒竟?jié)開頭查看ksh的版本所使用的命令:$set-oemacs或$set-ovi你會(huì)發(fā)現(xiàn)vi和emacs編輯模式擅長模擬這些編輯器的基本命令,而不是他們的高級(jí)特性。這是因?yàn)樗鼈兊闹饕康氖亲屇惆咽种噶?xí)慣從你最喜歡的編輯器轉(zhuǎn)移到Shell。15.2.2ksh的特性關(guān)于控制結(jié)構(gòu):ksh、sh、csh都有的控制結(jié)構(gòu)是if/else、for、case、while。而select控制結(jié)構(gòu)是在ksh中新加入的。select允許你方便地生成簡(jiǎn)單的菜單。它具有簡(jiǎn)潔的語法,但卻做了相當(dāng)多的工作。它的語法如下所示:selectvname[inword…]do
listdone除了select關(guān)鍵字以外,它的語法和for語句的語法一樣。并且你也可以在select中省略in列表,它將默認(rèn)使用“$@”,即引用命令行參數(shù)的列表。15.2.2ksh的特性select所做的工作如下:(1)生成一個(gè)包含列表中的每一項(xiàng)的菜單,并為每個(gè)選項(xiàng)編號(hào);(2)提示用戶輸入一個(gè)編號(hào);(3)分別將選擇的選項(xiàng)存儲(chǔ)在變量vname中,選擇的編號(hào)存儲(chǔ)在內(nèi)部變量REPLY中;(4)執(zhí)行正文中的語句;(5)然后一直重復(fù)執(zhí)行此過程,除非遇到break語句。15.2.2ksh的特性關(guān)于調(diào)試功能:ksh具有幾個(gè)基本特性提供了調(diào)試的功能。其中最基本的是set命令中的幾個(gè)選項(xiàng),當(dāng)然這些選項(xiàng)同樣可以在命令行上運(yùn)行腳本時(shí)使用。set-o選項(xiàng)命令行選項(xiàng)的功能noexec與命令“set-n”功能相同不運(yùn)行命令,只檢查語法錯(cuò)誤verbose與命令“set-v”功能相同在運(yùn)行命令之前先打印它們xtrace與命令“set-x”功能相同在命令行處理之后打印它們15.2.2ksh的特性關(guān)于調(diào)試功能:ksh具有幾個(gè)基本特性提供了調(diào)試的功能。其中最基本的是set命令中的幾個(gè)選項(xiàng),當(dāng)然這些選項(xiàng)同樣可以在命令行上運(yùn)行腳本時(shí)使用。set-o選項(xiàng)命令行選項(xiàng)的功能noexec與命令“set-n”功能相同不運(yùn)行命令,只檢查語法錯(cuò)誤verbose與命令“set-v”功能相同在運(yùn)行命令之前先打印它們xtrace與命令“set-x”功能相同在命令行處理之后打印它們15.2.2ksh的特性ksh還提供了更復(fù)雜的調(diào)試輔助工具,即三個(gè)可以使用在trap語句中的“假信號(hào)”,它們可以使Shell在特定條件下采取行動(dòng)。這些假信號(hào)就像真的一樣,只不過它們是由Shell產(chǎn)生(而不是像真信號(hào),由底層的操作系統(tǒng)發(fā)出)。這三個(gè)信號(hào)及它們的含義分別如下所示:EXIT:當(dāng)Shell從函數(shù)或腳本中退出時(shí)會(huì)發(fā)送此信號(hào)。ERR:當(dāng)命令返回一個(gè)非0退出狀態(tài)時(shí)會(huì)發(fā)送此信號(hào)。DEBUG:在每個(gè)語句執(zhí)行后都會(huì)發(fā)送此信號(hào)。15.2.2ksh的特性關(guān)于ksh的安全特性:Linux(Unix或類Unix)系統(tǒng)的幾乎所有方面都有一些與之相關(guān)的安全問題,它通常是系統(tǒng)管理員的工作所擔(dān)心的問題。而ksh具有幫助解決這個(gè)問題的三個(gè)特性,它們分別是:受限制的Shell、跟蹤別名功能和特權(quán)模式。受限制的Shell是設(shè)計(jì)用于將用戶放到一個(gè)他(她)的移動(dòng)能力和寫文件能力被嚴(yán)格限制的環(huán)境。它通常被用于訪客賬戶。你可以通過將rksh或ksh–r放入用戶的/etc/passwd條目中,來把用戶的登錄Shell變?yōu)槭芟拗频摹?5.2.2ksh的特性由受限制的Shell強(qiáng)加的特定約束將不允許用戶執(zhí)行如下操作:變更工作目錄:cd命令將是無效的。如果你嘗試使用此命令,將會(huì)得到錯(cuò)誤信息“ksh:cd:restricted”。重定向輸出到文件:重定向符>、>|、<>和>>將是不允許的。給環(huán)境變量SHELL、ENV和PATH指定新值。指定任何路徑名中帶有斜杠‘/’的路徑:Shell會(huì)將當(dāng)前目錄以外的文件視為“未找到”。跟蹤別名是ksh用于防止特洛伊木馬攻擊的一種方式。首先,它為幾乎所有常用工具,如ls、mv、cp、who、grep及很多其它工具,都定義了跟蹤別名。由于別名優(yōu)先于可執(zhí)行文件,所以別名將總是會(huì)運(yùn)行,而特洛伊木馬不會(huì)被運(yùn)行。15.2.2ksh的特性此外,如果你輸入命令“alias-t”想查看所有這些跟蹤別名,Shell不會(huì)讓你知道這些別名。所以如果你想入侵系統(tǒng)時(shí),你將很難找到一個(gè)可以作為你的特洛伊木馬的命令。這是一個(gè)非常聰明且未公開的安全特性。特權(quán)模式是ksh用于防治特洛伊木馬攻擊的另一種方式。它通過如下命令來實(shí)現(xiàn):$set-oprivileged或$set-p但每當(dāng)Shell執(zhí)行一個(gè)設(shè)置了suid位的腳本時(shí),它會(huì)自動(dòng)進(jìn)入特權(quán)模式。在特權(quán)模式下,當(dāng)一個(gè)具有suid的ksh腳本被調(diào)用時(shí),Shell不會(huì)運(yùn)行用戶的環(huán)境文件,即它不會(huì)擴(kuò)大用戶的ENV環(huán)境變量,而是運(yùn)行文件/etc/suid_profile。15.2.2ksh的特性配置文件/etc/suid_profile的編寫應(yīng)該以與受限制的Shell差不多的方式限制具有suid位的ksh腳本。至少,它應(yīng)該將PATH環(huán)境變量設(shè)為只讀,其命令如下所示:typeset-rPATH或readonlyPATH并將其設(shè)置為一個(gè)或多個(gè)安全目錄。再者,這樣可以防止任何誘餌被調(diào)用。由于特權(quán)模式是一個(gè)選項(xiàng),所以它可以使用如下命令來關(guān)閉:$set+oprivileged或$set+p這樣Shell會(huì)自動(dòng)將它的有效用戶ID改變?yōu)榕c真實(shí)用戶ID相同,即如果你關(guān)閉了特權(quán)模式,也就關(guān)閉了suid。特權(quán)模式是一個(gè)優(yōu)秀的安全特性。它解決了原來環(huán)境文件的概念第一次出現(xiàn)在CShell中時(shí)所引入的問題。15.2.3ksh的內(nèi)部變量你的環(huán)境中有一些特征,你可能想對(duì)其進(jìn)行定制,但它們卻又不能表示為一個(gè)開/關(guān)選項(xiàng)。這種類型的特征是指定在Shell變量中的。ksh中記錄了幾個(gè)Shell內(nèi)部變量。按照慣例,內(nèi)部變量的名稱都為大寫字母。定義變量的語法和別名的語法類似,如下所示:varname=value定義內(nèi)部變量的語法則為:VARNAME=value在等號(hào)‘=’的兩側(cè)都不能有空格,并且如果指定的值超過一個(gè)單詞,則它必須被等號(hào)括起。15.2.3ksh的內(nèi)部變量ksh中有幾個(gè)變量是與我們?cè)谏弦还?jié)中講到的命令行編輯模式相關(guān)。這些變量分別如下所示:COLUMNS:這個(gè)變量用于定于你的終端窗口的字符列寬度。它的標(biāo)準(zhǔn)值是80(有時(shí)是132),盡管如此,如果你使用類似于像XWindow這樣的窗口系統(tǒng)的話,你可以將終端窗口設(shè)置為任何你希望的大小。LINES:這個(gè)變量定義在文本行下你的終端的長度。終端的標(biāo)準(zhǔn)值是24。同樣地,如果你使用窗口系統(tǒng),你通??梢詫⑵湔{(diào)整為任意大小。HISTFILE:命令歷史文件的名稱。用于編輯模式操作。EDITOR:此變量用于定義文本編輯器的路徑名。后綴(emacs或vi)決定哪個(gè)編輯模式被使用。VISUAL:與EDITOR相似,如果EDITOR沒有被設(shè)置則使用此變量,反之亦然。FCEDIT:與fc命令結(jié)合使用的編輯器的路徑名。15.2.3ksh的內(nèi)部變量上述變量中前兩個(gè)有時(shí)會(huì)被文本編輯器和其它屏幕導(dǎo)向程序所使用,它們依賴于這兩個(gè)變量被正確地設(shè)置。盡管ksh和大部分窗口系統(tǒng)應(yīng)該知道怎樣正確地設(shè)置這兩個(gè)變量,但如果你的屏幕導(dǎo)向程序有顯示問題時(shí),你應(yīng)該查看一下變量COLUMNS和LINES的值。內(nèi)部變量TERM對(duì)于使用你的整個(gè)屏幕或窗口的任何程序來說都是極其重要的,比如文本編輯器。這樣的還包括所有屏幕編輯器(例如,vi和emacs)、more和無數(shù)的第三方應(yīng)用程序。因?yàn)橛脩艋ㄙM(fèi)越來越多的時(shí)間在程序上,而使用Shell卻越來越少,所以正確地設(shè)置你的TERM變量是極其重要的。在大部分情況下確實(shí)是系統(tǒng)管理員會(huì)幫你設(shè)置好它,但在你需要自己設(shè)置它的情況下,這里有一些指導(dǎo)方針。15.2.3ksh的內(nèi)部變量TERM的值必須是一個(gè)由小寫字母組成的,看起來像是terminfo數(shù)據(jù)庫中的文件名的短字符串。這個(gè)terminfo數(shù)據(jù)庫是在目錄/usr/lib/terminfo下的兩層目錄文件。這個(gè)目錄包含以單個(gè)字符命名的子目錄,它們依次包含名稱以那個(gè)字符開頭的所有終端的終端信息的文件。每個(gè)文件描述怎樣告訴有問題的終端做一些常見的事情,比如,把光標(biāo)移到屏幕上的適當(dāng)位置、滾動(dòng)屏幕、插入文本等等。這些描述是二進(jìn)制格式的。終端描述符文件的名稱和被描述的終端名是一樣的,有時(shí)會(huì)使用一個(gè)縮寫。例如,DECVT100在文件/usr/lib/terminfo/v/vt100中具有描述,一個(gè)XWindow系統(tǒng)下的xterm終端窗口在文件/usr/lib/terminfo/x/xterm中具有描述。15.2.3ksh的內(nèi)部變量有時(shí)你的Linux軟件會(huì)錯(cuò)誤地設(shè)置TERM變量,這通常發(fā)生在X終端和基于PC的Unix系統(tǒng)。所以在做進(jìn)一步的操作之前,你應(yīng)該先通過輸入命令“print$TERM”來檢查變量TERM的值。如果你發(fā)現(xiàn)你的Linux系統(tǒng)沒有為你設(shè)置正確的值,你就需要自己找到合適的TERM的值。如果你不能找到系統(tǒng)管理員來幫你做這件事的話,那么找到TERM的值的最好方法就是推測(cè)terminfo的名稱,并在目錄/usr/lib/terminfo下通過ls命令查找這個(gè)名稱的文件。例如,如果你的終端是BlivitzBL-35A,你可以嘗試如下命令:$cd/usr/lib/terminfo$lsb/bl*如果成功的話,你將看到類似如下的內(nèi)容:bl35ablivitz35a在這個(gè)示例中,這兩個(gè)名字類似于同一終端描述符的同義詞(軟鏈接),所有你可以使用它們中任一個(gè)作為TERM的值。換句話說,你可以把這兩行中的任一個(gè)放入你的.profile中:TERM=b135aTERM=blivitz35a15.2.3ksh的內(nèi)部變量如果沒執(zhí)行成功,它不會(huì)打印任何內(nèi)容,你就必須做另一個(gè)猜測(cè)再試一次。如果你發(fā)現(xiàn)terminfo不包含任何與你終端類似的內(nèi)容,那么你需要查閱你的終端手冊(cè)看看終端是否可以模擬更流行的模型,對(duì)于現(xiàn)在的大部分終端來說都是可以的。相反地,terminfo可能有多個(gè)條目關(guān)聯(lián)到你的終端,分別用于子模型、特定的模式等等。如果你有多個(gè)選擇可以作為你的TERM的值,我們建議你使用文本編輯器或其它任何你使用的屏幕導(dǎo)向程序測(cè)試每一個(gè)值來看哪一個(gè)最合適。15.2.3ksh的內(nèi)部變量另一個(gè)重要的內(nèi)部變量是PATH,但值得注意的是搜索你的PATH變量中的目錄可能會(huì)花費(fèi)時(shí)間,一些PATH搜索所涉及的大量磁盤讀寫操作的時(shí)間可能比你調(diào)用的命令的運(yùn)行時(shí)間還長。為此,ksh提供了一種避免PATH搜索的方法:即我們上一節(jié)中講過的跟蹤別名機(jī)制。首先請(qǐng)注意,如果你通過給出命令的全路徑來指定一個(gè)命令,那么Shell甚至不會(huì)使用你的PATH變量,而是會(huì)直接執(zhí)行文件。如果你開啟了跟蹤別名,那么你第一次調(diào)用一個(gè)別名時(shí),Shell會(huì)以正常的方式(通過PATH)查找可執(zhí)行文件。然后會(huì)把它最為別名來存儲(chǔ)命令的全路徑名,所以下次你再調(diào)用命令時(shí),Shell將使用全路徑名,就不會(huì)再搜索PATH。如果你修改了你的PATH,Shell會(huì)把跟蹤別名標(biāo)記為未定義,以便當(dāng)你調(diào)用相應(yīng)的命令時(shí),它會(huì)在再次搜索全路徑。15.2.3ksh的內(nèi)部變量事實(shí)上,你可以單純?yōu)榱吮苊饽憬?jīng)常使用的命令的PATH查找而添加跟蹤別名。只需將如下命令行放入你的.profile或環(huán)境文件中。Shell會(huì)自己替換命令的全路徑。alias-tcommand=commandksh的內(nèi)部變量CDPATH的值和PATH變量的值類似,是一個(gè)由冒號(hào)分隔的目錄列表。它的目的是增加內(nèi)部命令cd的功能。默認(rèn)情況下,CDPATH變量是不設(shè)置的(意味著它為空),并且當(dāng)你輸入命令“cddirname”時(shí),Shell將會(huì)在當(dāng)前目錄下查找名稱為dirname的子目錄(和PATH變量類似,當(dāng)dirname以斜杠‘/’開頭時(shí)是不會(huì)進(jìn)行此查找操作的)。如果你設(shè)置變量CDPATH,你就給Shell提供了一個(gè)查找dirname的位置列表,這個(gè)列表可能包含,也可能不包含當(dāng)前目錄。15.2.3ksh的內(nèi)部變量下面是一個(gè)例子,現(xiàn)在假設(shè)我們?cè)谀夸洝皛/work/projects/devtools/windows/confman”下有幾個(gè)子目錄是我們經(jīng)常要訪問的,它們分別叫做src、bin和doc。你定義你的CDPATH變量類似如下:CDPATH=:~/work/projects/devtools/windows/confman根據(jù)這個(gè)設(shè)置,如果你輸入命令“cddoc”,那么Shell將在當(dāng)前目錄下查找名稱為doc的子目錄。假設(shè)它沒有找到,它就會(huì)在CDPATH定義的目錄“~/work/projects/devtools/windows/confman”中查找。Shell在那里找到了doc目錄,所有就會(huì)直接切換到那個(gè)目錄下。這個(gè)特性在當(dāng)你需要經(jīng)常cd到你的文件層級(jí)較深的目錄中時(shí)為你提供了節(jié)省輸入的另一種方式。15.2.4ksh的內(nèi)部命令內(nèi)部命令有兩種類型:特殊內(nèi)部命令和常規(guī)內(nèi)部命令。特殊內(nèi)部命令與常規(guī)內(nèi)部命令的區(qū)別主要在如下幾個(gè)方面:特殊內(nèi)部命令的語法錯(cuò)誤可能引起Shell執(zhí)行命令的結(jié)束。而常規(guī)內(nèi)部命令的語法錯(cuò)誤不會(huì)發(fā)生這個(gè)問題。如果特殊內(nèi)部命令的語法錯(cuò)誤沒有結(jié)束Shell程序,那么它的退出值將是非0。由特殊內(nèi)部命令指定的變量賦值在命令結(jié)束之后仍然有效。輸入輸出重定向在參數(shù)賦值之后處理。下面我們就先來了解一下ksh的特殊內(nèi)部命令。15.2.4ksh的內(nèi)部命令.File[Argument…]:該命令用于讀取指定文件中的全部?jī)?nèi)容,然后將它們作為命令執(zhí)行。這些命令在當(dāng)前Shell環(huán)境中執(zhí)行。使用PATH變量指定的搜索路徑來查找包含這些命令的目錄。如果此命令后指定了參數(shù),它們將變?yōu)槲恢脜?shù),否則,位置參數(shù)不變。此命令的退出狀態(tài)是指定的File中最后一條被執(zhí)行的命令的退出狀態(tài)。注意:.File[Argument…]命令是在執(zhí)行任何命令之前先讀取整個(gè)文件的內(nèi)容。因此,指定的文件File中的alias和unalias命令不會(huì)應(yīng)用于定義在此文件中的任何函數(shù)。break[n]:用于從for、while、until或select循環(huán)中退出。如果你指定了參數(shù)n,此命令會(huì)中斷由參數(shù)n指定的層級(jí)數(shù)。參數(shù)n的值只大于等于1的任意整數(shù)。continue[n]:繼續(xù)for、while、until或select循環(huán)的下一個(gè)迭代。如果你指定了參數(shù)n,命令會(huì)在循環(huán)的第n個(gè)迭代繼續(xù)。參數(shù)n的值是大于等于1的任意整數(shù)。15.2.4ksh的內(nèi)部命令eval[Argument…]:讀取指定的參數(shù)作為Shell的參數(shù),并執(zhí)行生成的命令或命令。exec[Argument…]:在當(dāng)前Shell下(并不創(chuàng)建新的進(jìn)程)執(zhí)行由參數(shù)指定的命令。輸入輸出參數(shù)可以出現(xiàn)并影響當(dāng)前進(jìn)程。如果你不指定參數(shù),exec命令會(huì)修改由輸入輸出重定向列表規(guī)定的文件描述符。在這種情況下,任何以這種機(jī)制打開的大于2的文件描述符在調(diào)用其它程序時(shí)都會(huì)關(guān)閉。exit[n]:以由參數(shù)n指定的退出狀態(tài)退出Shell。參數(shù)n必須是一個(gè)范圍為0到255的無符號(hào)十進(jìn)制整數(shù)。如果你省略參數(shù)n,則退出狀態(tài)是最后一條執(zhí)行命令的退出狀態(tài)。除非在特殊內(nèi)部命令set的ignoreeof選項(xiàng)開啟的情況下,EOF字符同樣也會(huì)退出Shell。export[-p][Name[=Value]]:標(biāo)記指定的變量自動(dòng)輸出到后續(xù)執(zhí)行命令的環(huán)境中。-p選項(xiàng)用于將所有輸出的變量的Name和Value寫到標(biāo)準(zhǔn)輸出,其格式類似如下所示:exportName=Value15.2.4ksh的內(nèi)部命令newgrp[Group]:相當(dāng)于如下命令:exec/usr/bin/newgrp
[Group]注意:這個(gè)命令不返回。readonly[-p][Name[=Value]]…:將由參數(shù)Name指定的變量標(biāo)記為只讀。這些變量不能被后續(xù)的賦值所修改。return[n]:使Shell函數(shù)返回到調(diào)用的腳本。返回狀態(tài)由參數(shù)n指定。如果你省略參數(shù)n,返回狀態(tài)最后一個(gè)執(zhí)行的命令的返回狀態(tài)。如果你在函數(shù)或腳本的外部調(diào)用return命令,那么它等同于exit命令。set[+|-abCefhkmnostuvx][+|-o
Option]...[+|-AName][Argument...]:如果不指定任何參數(shù)和選項(xiàng),set命令會(huì)顯示當(dāng)前環(huán)境中的所有Shell變量的名稱和值。當(dāng)指定了選項(xiàng)時(shí),它們將設(shè)置或取消Shell的相應(yīng)屬性。15.2.4ksh的內(nèi)部命令shift[n]:從$n+1開始到$1,重命名位置參數(shù)。參數(shù)n的默認(rèn)值是1。參數(shù)n可以是任何其值為小于或等于特殊參數(shù)$#的非負(fù)整數(shù)的算術(shù)表達(dá)式。times:打印Shell的或從Shell運(yùn)行的進(jìn)程的累積用戶和系統(tǒng)時(shí)間。trap[Command][Signal]…:當(dāng)Shell收到指定的信號(hào)時(shí)運(yùn)行指定的命令。參數(shù)Command在設(shè)置捕獲時(shí)讀取一次和當(dāng)捕獲被處理時(shí)讀取一次。參數(shù)Signal可以通過數(shù)值或信號(hào)名指定。設(shè)置捕獲被當(dāng)前忽略的信號(hào)的任何嘗試都將是無效的。如果參數(shù)是-,所有的捕獲都將被重置為它們的原始值。如果參數(shù)Signal的值是ERR,那么每當(dāng)命令的退出狀態(tài)為非0時(shí),指定的命令Command被執(zhí)行。如果信號(hào)是DEBUG,那么在每個(gè)命令執(zhí)行之后指定的命令Command會(huì)被執(zhí)行。如果參數(shù)Signal的值是0或EXIT信號(hào)并且trap命令是在函數(shù)內(nèi)執(zhí)行,那么指定的命令Command是在函數(shù)運(yùn)行完成后執(zhí)行。如果參數(shù)Signal的值是0或EXIT信號(hào),而trap命令設(shè)置在任何函數(shù)之外,那么指定的命令Command是在退出Shell時(shí)執(zhí)行。不帶任何參數(shù)的trap命令會(huì)打印與每個(gè)信號(hào)關(guān)聯(lián)的命令列表。如果指定的Command為空,表示為""(空雙引號(hào)),那么ksh命令將忽略信號(hào)。15.2.4ksh的內(nèi)部命令typeset
[+HLRZfilrtux
[n]][Name[=Value]]...:為Shell參數(shù)設(shè)置屬性和值。當(dāng)此命令在函數(shù)內(nèi)被調(diào)用時(shí),參數(shù)Name的新實(shí)例將被創(chuàng)建。當(dāng)函數(shù)執(zhí)行完成時(shí)參數(shù)的值和類型會(huì)恢復(fù)。unset
[-fv
]
Name
...:注銷由Name指定的變量或函數(shù)的屬性和值。如果指定了-v選項(xiàng),那么參數(shù)Name代表變量名,Shell將把它從環(huán)境中注銷并移除。只讀變量可以被注銷。注銷ERRNO、LINENO、MAILCHECK、OPTARG、OPTIND、RANDOM、SECONDS、TMOUT和下劃線(_)變量將移除它們的特殊含義,即使它們是后來被賦值的。如果指定了-f選項(xiàng),那么參數(shù)Name代表函數(shù)名,Shell將注銷指定函數(shù)的定義。15.2.4ksh的內(nèi)部命令ksh還提供了一些常規(guī)的內(nèi)部命令,接下來我們來一起學(xué)習(xí)了解一下。alias[-t][-x][AliasName[=
String]]...:創(chuàng)建或重新定義別名,或顯示現(xiàn)有的別名定義到標(biāo)準(zhǔn)輸出。實(shí)例1:修改ls命令使它顯示文件的詳細(xì)信息:$aliasls='ls-CF'實(shí)例2:使用1KB單位的du命令:$aliasdu=du\-k實(shí)例3:查看ls命令的全路徑:$alias-tlsls=/usr/bin/lsbg
[JobID...]:把指定的作業(yè)放到后臺(tái)執(zhí)行。如果沒有指定參數(shù)JobID,則把當(dāng)前的作業(yè)放到后臺(tái)執(zhí)行。15.2.4ksh的內(nèi)部命令實(shí)例1:如果jobs命令的輸出顯示有如下停止的作業(yè):[2]+Stopped(SIGSTOP)sleep100&我們可以使用如下命令使作業(yè)sleep100&繼續(xù)運(yùn)行:$bg%2屏幕將顯示作業(yè)2的新狀態(tài):[2]sleep100&15.2.4ksh的內(nèi)部命令fg
[JobID]:把指定的作業(yè)放到前臺(tái)運(yùn)行。如果你沒有指定任何作業(yè),此命令會(huì)把當(dāng)前作業(yè)放到前臺(tái)運(yùn)行。實(shí)例1:比如我們運(yùn)行了如下命令:$sleep100&[1]30140使用命令jobs-l,我們將看到如下作業(yè)在后臺(tái)運(yùn)行,其作業(yè)ID為1:$jobs-l[1]+30140Runningsleep100&現(xiàn)在我們使用如下命令,將上述作業(yè)放到前臺(tái)運(yùn)行:$fg%1這時(shí)你在屏幕上將看到如下信息:sleep10015.2.4ksh的內(nèi)部命令sleep100getoptsOptionStringName[Argument…]:處理命令行參數(shù)和檢查有效的選項(xiàng)。實(shí)例1:如下的getopts命令指定a、b、c是有效的選項(xiàng),并且選項(xiàng)a和c具有參數(shù):getoptsa:bc:OPT實(shí)例2:下面的getopts命令指定a、b、c是有效選項(xiàng),選項(xiàng)a和b有參數(shù),而當(dāng)遇到一個(gè)未定義的命令行選項(xiàng)時(shí),getopts會(huì)將OPT的值設(shè)為?getopts:a:b:cOPT15.2.4ksh的內(nèi)部命令jobs[-l|-n|-p][JobID...]:顯示在當(dāng)前Shell環(huán)境下啟動(dòng)的作業(yè)的狀態(tài)。如果沒有指定JobID,將顯示所有活躍的作業(yè)的狀態(tài)信息。如果一個(gè)作業(yè)被報(bào)告為終結(jié),Shell會(huì)將此作業(yè)的進(jìn)程ID從當(dāng)前Shell環(huán)境已知的列表中移除。實(shí)例1:顯示當(dāng)前Shell環(huán)境下所有作業(yè)的狀態(tài),輸入如下命令:$jobs-l屏幕會(huì)顯示類似如下的輸出信息:+[4]139Runningsleep50&-[3]465Stoppedmailyantaol[2]687Done(1)foo.bar&實(shí)例2:若要顯示其名稱以字母s開頭的作業(yè)的進(jìn)程ID,輸入如下命令:$jobs-p%s我們使用實(shí)例1中報(bào)告的作業(yè),屏幕將顯示如下所示的進(jìn)程ID:13915.2.4ksh的內(nèi)部命令kill命令,用于發(fā)送一個(gè)信號(hào)到運(yùn)行的進(jìn)程。其語法類似如下所示:kill[-s{SignalName|SignalNumber}]ProcessID...kill[-SignalName|-SignalNumber]ProcessID...實(shí)例1:終止指定的進(jìn)程。如要終止PID為1095的進(jìn)程,輸入類似如下命令:$kill1095實(shí)例2:停止忽略默認(rèn)信號(hào)的進(jìn)程,使用類似如下的命令:$kill-kill20981569上述命令將發(fā)送信號(hào)9,即SIGKILL信號(hào),到進(jìn)程ID為2098和1569的進(jìn)程。信號(hào)SIGKILL是通常不能被忽略和覆蓋的特殊信號(hào)。實(shí)例3:停止所有你自己的進(jìn)程并注銷你的賬號(hào),使用如下命令:$kill-kill0上述命令發(fā)送信號(hào)9(SIGKILL信)到進(jìn)程組ID等于發(fā)送者的進(jìn)程組ID的所有進(jìn)程。因?yàn)镾hell不能忽略SIGKILL信號(hào),所以這個(gè)賬號(hào)同樣會(huì)停止登錄Shell。實(shí)例4:停止你自己的所有進(jìn)程,使用類似如下命令:$kill-9-1上述命令發(fā)送信號(hào)9到由有效用戶擁有的所有進(jìn)程,即使這些進(jìn)程啟動(dòng)在其它作業(yè)區(qū),或是屬于其它進(jìn)程組。實(shí)例5:發(fā)送一個(gè)不同的信號(hào)代碼到一個(gè)進(jìn)程,使用類似如下命令:$kill-USR11103kill命令的名稱很容易給人造成誤解,因?yàn)楹芏嘈盘?hào)是不終止進(jìn)程的,比如SIGUSR1信號(hào)。信號(hào)SIGUSR1所采取的行為由你運(yùn)行的特定程序定義。15.2.4ksh的內(nèi)部命令letExpression...:對(duì)算術(shù)表達(dá)式求值。如果最后一個(gè)表達(dá)式的值為非0,那么其退出狀態(tài)為0,否則為1。實(shí)例1,求一個(gè)簡(jiǎn)單表達(dá)式8*(10-3)的值,使用類似如下的命令:$let"y=8*(10-3)"
$echo$y56pwd命令,相當(dāng)于命令print-r-$PWD。ksh的內(nèi)部命令pwd不支持軟鏈接。read[-prsu[n]][Name?Prompt][Name...]:獲取Shell輸入。讀取一行的內(nèi)容,并使用變量IFS變量中的字符將其分為若干列。實(shí)例1:下面一段腳本代碼用于打印文件的內(nèi)容,將文件中每行第一列的內(nèi)容移到行尾:whileread-rxxyydoprintf
"%s
%s/n"
$yy
$xxdone<InputFile實(shí)例2:從命令行讀取輸入并將其分隔為列,并使用“Pleaseenter:”作為提示,其命令類似如下所示:$readword1?"Pleaseenter:"word2運(yùn)行上述命令后,系統(tǒng)將顯示:Pleaseenter:此時(shí),如果你輸入helloworld后回車,將得到類似如下結(jié)果:Pleaseenter:helloworld$echo$word1hello$echo$word2world15.2.4ksh的內(nèi)部命令setgroups命令,執(zhí)行/usr/bin/setgroups命令,此命令會(huì)作為一個(gè)單獨(dú)的Shell運(yùn)行。ksh中還存在一個(gè)內(nèi)部命令setgroups,此命令會(huì)調(diào)用一個(gè)子Shell,而/usr/bin/setgroups與其不同,它會(huì)替換當(dāng)前運(yùn)行的Shell。因?yàn)榇藘?nèi)部命令只是為了兼容性而支持,所以還是建議腳本使用絕對(duì)路徑/usr/bin/setgroups而不是此內(nèi)部命令。實(shí)例1:直接使用setgroups命令,你可以顯示你當(dāng)前的組成員關(guān)系和進(jìn)程組的設(shè)置。其輸出類似如下所示:$setgroupsyantaol:
usergroups=staff,payrollprocessgroups=staff,payroll實(shí)例2:添加finance組到當(dāng)前會(huì)話的進(jìn)程組,使用類似如下命令:$setgroups-afinance實(shí)例3:設(shè)置你的真實(shí)組到為finance,使用類似如下命令:$setgroupsfinance,staff,payroll上述命令設(shè)置finance為真實(shí)組。組staff和payroll構(gòu)成補(bǔ)充組列表。實(shí)例4:從當(dāng)前進(jìn)程組設(shè)置中刪除payroll組,使用類似如下命令:$setgroups-dpayroll實(shí)例5:將進(jìn)程組設(shè)置改回你的默認(rèn)設(shè)置,使用類似如下命令:15.2.4ksh的內(nèi)部命令$setgroups-上述命令將你的當(dāng)前會(huì)話重置為你登錄后的最初狀態(tài)。setsenv命令,執(zhí)行/usr/bin/setsenv命令,此命令的運(yùn)行將替換當(dāng)前執(zhí)行的Shell。實(shí)例1:顯示當(dāng)前的環(huán)境變量,其命令類似如下所示:$setsenv實(shí)例2:添加PSEUDO=yantaol為受保護(hù)的環(huán)境變量,其命令類似如下所示:$setsenvPSEUDO=yantaol上述命令為受保護(hù)環(huán)境變量PSEUDO設(shè)置一個(gè)用戶名。15.2.4ksh的內(nèi)部命令test命令,與[expression]相同。ulimit[-HSacdfmst][Limit]:設(shè)置或顯示定義在文件/etc/security/limits中的用戶進(jìn)程資源限制。此文件中定義的值被作為用戶添加到系統(tǒng)時(shí)的默認(rèn)設(shè)置。這些值可以在用戶添加到系統(tǒng)時(shí)使用mkuser命令設(shè)置,或使用chuser命令修改。限制被分為軟限制和硬限制兩種。用戶可以使用ulimit命令修改它們的軟限制到硬限制的最大值。你必須有root用戶權(quán)限才能修改資源硬限制。umask[-S][Mask]:確定文件權(quán)限。它的值與創(chuàng)建進(jìn)程的權(quán)限一起,決定文件創(chuàng)建時(shí)的權(quán)限。它的默認(rèn)是022。如果沒有指定參數(shù)Mask,umask命令會(huì)在標(biāo)準(zhǔn)輸出上顯示當(dāng)前Shell環(huán)境的文件模式創(chuàng)建掩碼。15.2.4ksh的內(nèi)部命令unalias{-a|AliasName...}:移除每個(gè)指定的AliasName或所有的別名定義。wait[ProcessID...]:等待指定的作業(yè)和終端。如果你不指定一個(gè)作業(yè),此命令會(huì)等待所有當(dāng)前活躍的子進(jìn)程。此命令的退出狀態(tài)是它等待的那個(gè)進(jìn)程的退出狀態(tài)。whence[-pv]Name...:指示指定的參數(shù)Name如果被作為一個(gè)命令名將被怎樣地解釋。如果不指定任何選項(xiàng),whence命令將顯示指定的參數(shù)Name對(duì)應(yīng)的絕對(duì)路徑名(如果存在)。15.2.5增強(qiáng)的ksh-ksh93ksh93是KornShell的最新版本,這個(gè)增強(qiáng)版本不僅向前兼容舊版本的ksh(ksh88),還包括了一些在ksh88中不可用的額外特性。一些腳本在ksh93下運(yùn)行與在ksh88下相比也會(huì)有所不同,因?yàn)檫@兩個(gè)ksh下的變量處理有點(diǎn)不同。下面就讓我們來了解一下,與ksh88相比,ksh93引入了哪些新特性。15.2.5增強(qiáng)的ksh-ksh93算法改進(jìn):你可以在算術(shù)表達(dá)式中使用libm函數(shù)庫(典型的C語言中的函數(shù)),例如“value=$((sqrt(9)))”。有更多的算術(shù)操作符可用,包括一元操作符+、++、--和?:結(jié)構(gòu)(例如,“x?y:z”),以及‘,’(逗號(hào))操作符。支持64位的算術(shù)運(yùn)算,還支持浮點(diǎn)運(yùn)算?!皌ypeset-E”可以用于指定有效位的個(gè)數(shù),而“typeset-F”可以用于指定一個(gè)算術(shù)變量小數(shù)位的個(gè)數(shù)。SECONDS變量現(xiàn)在可以顯示精確到百分位的秒數(shù)而不是只精確到個(gè)位的。15.2.5增強(qiáng)的ksh-ksh93支持復(fù)合變量:ksh93增加了對(duì)復(fù)合變量的支持。復(fù)合變量允許用戶在一個(gè)變量名內(nèi)指定多個(gè)值。其語句類似如下所示:$myvar=(x=1y=2)若要分別顯示myvar變量的兩個(gè)值,則其語法類似如下所示:$echo${myvar.x}1$echo${myvar.y}2從上述的語法我們可以看出,若要使用每個(gè)下標(biāo)變量的值,需要在父變量與下標(biāo)變量之間使用句號(hào)(.)分隔。15.2.5增強(qiáng)的ksh-ksh93支持復(fù)合賦值:在初始化數(shù)組時(shí)ksh93支持復(fù)合賦值,并對(duì)索引數(shù)組和聯(lián)合數(shù)組都支持。指定的值被放在圓括號(hào)中,復(fù)合賦值的語句類似如下所示:$numbers=(zeroonetwothree)下面我們查看數(shù)組numbers中元素的值,使用類似如下語句:$echo${numbers[0]}zero$echo${numbers[2]}two15.2.5增強(qiáng)的ksh-ksh93支持聯(lián)合數(shù)組:聯(lián)合數(shù)組是使用字符串作為索引的數(shù)組。在ksh93下,使用typeset命令的-A選項(xiàng)允許你指定一個(gè)聯(lián)合數(shù)組。類似如下所示:$typeset-Astudentsnum$studentsnum=([class1]=35[class2]=29)若要顯示上述聯(lián)合數(shù)組中某個(gè)元素的值,使用類似如下語句:$echo${studentsnum
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年新型工業(yè)廠房電氣設(shè)備安裝與調(diào)試服務(wù)合同3篇
- 2025年度綠化景觀工程養(yǎng)護(hù)與后期維護(hù)合同4篇
- 二零二五年照明行業(yè)項(xiàng)目投資與融資服務(wù)合同范本3篇
- 2025年度畜牧養(yǎng)殖飼料添加劑研發(fā)與應(yīng)用合同4篇
- 2025年度文化展覽場(chǎng)地租賃及展覽策劃合同3篇
- 2025年度智能制造行業(yè)個(gè)人勞動(dòng)合同模板4篇
- 2025年度汽車內(nèi)飾產(chǎn)品加工與環(huán)保認(rèn)證合同3篇
- 2025年度環(huán)保門窗材料采購與安裝工程合同4篇
- 二零二五年度石油交易平臺(tái)會(huì)員服務(wù)合同4篇
- 2025年度櫥柜安裝與整體廚房解決方案合同4篇
- 2024版智慧電力解決方案(智能電網(wǎng)解決方案)
- 公司SWOT分析表模板
- 小學(xué)預(yù)防流行性感冒應(yīng)急預(yù)案
- 肺癌術(shù)后出血的觀察及護(hù)理
- 聲紋識(shí)別簡(jiǎn)介
- 生物醫(yī)藥大數(shù)據(jù)分析平臺(tái)建設(shè)-第1篇
- 基于Android的天氣預(yù)報(bào)系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
- 沖鋒舟駕駛培訓(xùn)課件
- 美術(shù)家協(xié)會(huì)會(huì)員申請(qǐng)表
- 聚合收款服務(wù)流程
- 中石化浙江石油分公司中石化溫州靈昆油庫及配套工程項(xiàng)目環(huán)境影響報(bào)告書
評(píng)論
0/150
提交評(píng)論