- 論壇徽章:
- 0
|
目標(biāo)
完成這一章,你可以做到以下事情:
※使用shell的替代功能,包括變量替代,命令替代,和波浪號(hào)替代。
※設(shè)置和修改shell變量。
※將局部變量傳給環(huán)境。
※ 使變量對(duì)子進(jìn)程生效。
※ 解釋進(jìn)程是如何被創(chuàng)建的。
7.0 shell 的替代功能
在shell 中有三種類型的替代:
※變量替代
※命令替代
※波浪號(hào)替代
替代的作用是加速命令行的鍵入和執(zhí)行
7.1 Shell 變量存儲(chǔ)
Shell內(nèi)有兩塊內(nèi)存區(qū)域用于存儲(chǔ)shell變量,它們是:局部數(shù)據(jù)區(qū)域和環(huán)境。當(dāng)定義了一個(gè)新的變量時(shí),內(nèi)存會(huì)被分配給局部數(shù)據(jù)區(qū)域,在這個(gè)區(qū)域中的變量是當(dāng)前shell
私有的,通常稱為局部變量,任何以后的子進(jìn)程都不會(huì)存取到這些局部變量。但是,子進(jìn)程能夠存取那些傳送到環(huán)境中去的變量。
在你的登錄進(jìn)程過(guò)程中,有幾個(gè)特殊的shell變量會(huì)被定義。其中大多數(shù)的變量存儲(chǔ)在環(huán)境中:一些變量,例如 ps1
和ps2,存儲(chǔ)在局部數(shù)據(jù)區(qū)域。這些變量的值能夠被改變,用于定制你的終端特性。
env 命令能夠顯示當(dāng)前保存在環(huán)境中所有的變量,例如:
$ env
MANPATH=/usr/share/man: /usr/contrib/man: /usr/local/man
PATH=/usr/bin: /usr/ccs/bin:/usr/contrib/bin: /usr/local/bin
LOGNAME=user3
ERASE=^H
SHELL=/usr/bin/sh
HOME=/home/user3
TERM=hpterm
PWD=/home/user3
TZ=PST8PDT
EDTOR=/usr/bin/vi
7.2 設(shè)置Shell變量
語(yǔ)法: name=value
例子:
$color=lavender ?? ? ?????? 給一個(gè)局部變量賦值
$count=3 ?????????????? 給一個(gè)局部變量賦值
$dir_name=tree/car.models/ford ?? 給一個(gè)局部變量賦值
$PS1=hi_there?????????? ? 更改環(huán)境變量的值
$set ??????????? ?????顯示所有的變量和值
當(dāng)一個(gè)用戶創(chuàng)建了一個(gè)新的變量,例如 color ,這個(gè)變量會(huì)存儲(chǔ)在局部數(shù)據(jù)區(qū)域中。當(dāng)給一個(gè)已經(jīng)存在的環(huán)境變量賦予一個(gè)新值,例如 path
,這個(gè)新值會(huì)代替環(huán)境中的舊的值。
7.3 變量替代
1.語(yǔ)法:
$name ?????執(zhí)行一個(gè)變量替代
例子:
$ echo $PATH
/usr/bin:/usr/contrib/bin:/usr/local/bin:/home/user3:.
$ echo $HOME
/home/user3
$file_name=$HOME/file1
$more $file_name
每一個(gè)變量都有一個(gè)關(guān)聯(lián)值。當(dāng)使用“$變量名”來(lái)對(duì)這個(gè)變量進(jìn)行引用時(shí) ,shell
會(huì)用變量的值來(lái)代替這個(gè)參數(shù)。這個(gè)過(guò)程被稱為變量替代,這是shell在執(zhí)行輸入的命令前執(zhí)行的任務(wù)之一。在shell
完成了所有的命令行的變量替代后,就會(huì)開始執(zhí)行這個(gè)命令。因此,變量可以代替命令,命令參數(shù),或者一條完整的命令行。這提供了一種機(jī)制來(lái)方便用戶重命名哪些經(jīng)常使用的長(zhǎng)的路徑名,或長(zhǎng)的命令字符串。
例子:
上例示范了一些shell變量的用法。請(qǐng)注意,變量替代能夠出現(xiàn)在命令行的任何位置,在一個(gè)命令行中可以有多個(gè)變量。如上例所示,一個(gè)已經(jīng)存在的變量的值能夠用來(lái)更新當(dāng)前變量的值。
$ echo $PATH
/usr/bin:/usr/contrib/bin:/usr/local/bin
$ PATH=$PATH:$HOME:.
$echo $ PATH
/usr/bin:/usr/contrib/bin:/usr/local/bin:/home/user3:.
$ echo $HOME
/home/user3
$ file_name=$HOME/file1 file_name=/home/user3/file1
$ more $file_name more /home/user3/file1
echo $name 命令是最常用的方式用于顯示變量當(dāng)前的值。
{} 的用法
確認(rèn)你有一個(gè)叫file和一個(gè)叫file1的變量。能夠使用以下的語(yǔ)句給它們賦值:
$ file =this
$ file1= that
$echo $fileand$file1 尋找變量fileand,file1
sh: fileand: parameter not set
$ echo ${file} and $file1 尋找變量file,file1
thisandthat
2.花括號(hào)被用來(lái)區(qū)分變量名和周圍的文本。
7.4 變量替代(2)
$dir_name=tree/car.models/ford
$echo $dir_name
tree/car.models/ford
$ls –F $dir_name
sedan/ sports/
$ my_ls =”ls –aFC”
$ $my_ls
./ file.1 tree/
../ file.2
$ $my_ls $dir_name
./ ../ sedan/ sports/
$ cd /tmp
$ dir_name=/home/user2/tree/dog.breeds/retriever
$ $my_ls $dir_name
./ ../ golden labrador mixed
在指定一個(gè)文件或目錄時(shí),使用一個(gè)絕對(duì)路徑作為一個(gè)變量的值。會(huì)讓你在文件系統(tǒng)的任何位置都可以存取你想要的文件或目錄。
上例的解釋:
$dir_name= tree/car.models/ford
$ echo $dir_name echo tree/car.models/ford
tree/car.models/ford
$ ls –F $dir_name ls –F tree/car.models/ford
swdan/ sports/
$ my_ls = “l(fā)s –aFC” 使用引號(hào)讓shell 忽略空格
$ $my_ls ls -aFC
./ file.1 tree/
../ file.2
$my_ls $dir_name ls –aFC tree/car.models/ford
./ ../ sedan/ sports/
$ cd /tmp
$ dir_name=/home/user2/tree/dog.breeds/retriever
$ $my_ls $dir_name ls –aFC /home/user2/tree/dog,breeds/retriever
./ ../ golden labrador mixed
7.5 命令替代
語(yǔ)法:
$(command)
例子:
$pwd
/home/user2
$ curdir=$(pwd)
$ echo $curdir
/home/user2
$ cd /tmp
$ pwd
$ cd $curdir
$ pwd
/home/user2
命令替代用來(lái)替代一個(gè)命令和命令行輸出。命令替代的標(biāo)準(zhǔn)語(yǔ)法,也是POSIX鼓勵(lì)的一種語(yǔ)法是:$(command).
命令替代讓你捕獲一個(gè)命令的輸出,用它作為另一個(gè)命令的參數(shù),或是賦值給一個(gè)變量。象在變量替代中的一樣,命令替代的執(zhí)行是在命令行開始之前完成的。當(dāng)命令行輸出包含回車換行,它們會(huì)被空格代替。
同變量替代相似,命令替代使用一個(gè)美元符號(hào)之后的用括號(hào)包圍的一個(gè)命令。 所有有效的shell腳本都可以加入命令替代。Shell
掃描每行腳本,執(zhí)行它發(fā)現(xiàn)的開始于一個(gè)開括號(hào),結(jié)束與于一個(gè)閉括號(hào)的命令。
命令替代的另外一種格式是用單引號(hào)來(lái)環(huán)繞一個(gè)命令象:
‘command’
它和$(command) 是等價(jià)的,并且這是Bourne
Shell認(rèn)證的唯一的形式!痗ommand’形式可以用在POSIX的腳本中和Bourne Shell的腳本中。
命令替代通常是在將一個(gè)命令的輸出賦給一個(gè)變量或以后的處理時(shí)使用。通常pwd命令將它的輸出送到你的屏幕。當(dāng)你執(zhí)行以下的賦值語(yǔ)句:
$ curdir=$(pwd) 或 $ curdir=’pwd’
pwd 的輸出被賦給變量 curdir。
7.6 波浪號(hào)替代
$ echo $HOME
/home/user3
$ echo ~
/home/user3
$ cd tree
$ echo $PWD
/home/user3/tree
$ ls ~+ /dog.breeds
collie poodle
$ehco $OLDPWD
/home/user3/mail
$ ls ~-
/home/user3/mail/from.mike /home/user3/mail/form.jim
$echo ~tricia/file1
/home/tricia/file1
如果一個(gè)單詞以一個(gè)波浪符(~)開頭,這個(gè)單詞被執(zhí)行一個(gè)波浪符擴(kuò)充,注意波浪符擴(kuò)充只在一個(gè)單詞的開始才會(huì)起作用,這個(gè)意思是:/~home/user3
沒(méi)有波浪號(hào)擴(kuò)充的功能,波浪擴(kuò)充有以下的規(guī)則:
單個(gè)地波浪號(hào)或是在/ 之前代表HOME變量中設(shè)置的路徑名。
一個(gè)波浪號(hào)跟一個(gè)+號(hào)代表PWD變量的值。PWD的值是在cd 到一個(gè)新的,當(dāng)前的,工作目錄時(shí)被設(shè)定的。
一個(gè)波浪號(hào)跟一個(gè)-號(hào)會(huì)代表OLDPWD變量的值。OLDPWD變量是在cd 前一個(gè)工作目錄時(shí)被設(shè)定的。
如果一個(gè)波浪號(hào)跟一個(gè)字符串,然后是一個(gè)/ 符號(hào) ,shell
會(huì)檢查字符串是否與用戶在系統(tǒng)中的名字一致。如果一致,~字符串會(huì)被用戶登錄的路徑名所代替。
波浪符號(hào)也能在別名中引用:
$pwd
/home/user3
$alias cdn=’cd ~/bin’
$ cdn
$pwd
/home/user3/bin
7.7 顯示變量的值 $ echo $HOME
/home/user3
$env
HOME=/home/user3
PATH=/usr/bin:/usr/contrib/bin:/usr/local/bin
SHELL=/usr/bin/sh
$ set
HOME=/home/user3
PATH=/usr/bin:/usr/contrib/bin:/usr/local/bin
SHELL=/usr/bin/sh
dolor=lavender
dir_name=/home/user3/tree
$ unset dir_name
變量替代,($變量),可以被用來(lái)顯示一個(gè)獨(dú)立變量的值,無(wú)論這個(gè)變量是在本地?cái)?shù)據(jù)區(qū)域或是在環(huán)境中。
env 命令用來(lái)顯示所有的當(dāng)前環(huán)境中的定義的變量,和它們的值。
set 命令會(huì)顯示所有的當(dāng)前定義的變量,本地和環(huán)境中的變量,和它們的值。 unset 命令用來(lái)刪除指定變量的當(dāng)前的值。這個(gè)指被賦為空值
NULL。
set 和unset 都是shell內(nèi)建的命令,而env 是UNIX命令 /usr/bin/env.
7.8 傳送局部變量到環(huán)境
語(yǔ)法:
export 變量 傳遞變量到環(huán)境
傳送變量 color和 count 到環(huán)境的過(guò)程,執(zhí)行了以下的命令:
$ color=lavender
$ export color
$ export count=3
$ export
export PATH=/usr/bin:/usr/ccs/bin:/usr/contrib/bin:/usr/local/bin
export color=lavender
export count=3
為了使其它的進(jìn)程也能使用一個(gè)變量,這個(gè)變量必須在環(huán)境中存在。當(dāng)一個(gè)變量被定義,這個(gè)變量存儲(chǔ)在局部數(shù)據(jù)空間,必須被export
到環(huán)境中去。
exprot 命令將指定的變量從局部數(shù)據(jù)空間傳遞到環(huán)境數(shù)據(jù)空間,export 變量=值
會(huì)對(duì)變量進(jìn)行賦值(也可能是更新),同時(shí)將這個(gè)變量放到環(huán)境中去。如果不帶參數(shù),export
命令同env命令一樣會(huì)顯示所有exported(輸出的),變量的名字和值,注意 export 是一個(gè)shell內(nèi)部的命令!
7.9 傳遞變量給一個(gè)應(yīng)用
系統(tǒng)中的每一個(gè)應(yīng)用或命令都會(huì)有一個(gè)相關(guān)聯(lián)的存儲(chǔ)在磁盤上的程序文件。大多數(shù)的UNIX系統(tǒng)命令在目錄/usr/bin
下面。當(dāng)執(zhí)行一個(gè)命令的時(shí)候,命令相關(guān)的程序文件必須被定位,再將代碼裝載入內(nèi)存然后執(zhí)行。在UNIX系統(tǒng)中一個(gè)運(yùn)行中的程序被稱為進(jìn)程。
當(dāng)你登錄進(jìn)入一個(gè)UNIX系統(tǒng)時(shí),shell 程序會(huì)被裝載,一個(gè)shell
進(jìn)程會(huì)被執(zhí)行。當(dāng)你在shell提示符下輸入一個(gè)應(yīng)用的(或命令)的名字后,一個(gè)子進(jìn)程會(huì)被創(chuàng)建和執(zhí)行:其過(guò)程如下:
一個(gè)fork(分叉)會(huì)復(fù)制你的shell進(jìn)程,包括程序代碼,環(huán)境數(shù)據(jù)空間,和局部數(shù)據(jù)空間。
一個(gè)exec 會(huì)使用子進(jìn)程的代碼和本地?cái)?shù)據(jù)空間來(lái)替代原進(jìn)程的本地?cái)?shù)據(jù)空間。
exec 會(huì)在執(zhí)行要求的應(yīng)用進(jìn)程后結(jié)束。
當(dāng)子進(jìn)程在執(zhí)行的時(shí)候,shell
(父進(jìn)程)會(huì)進(jìn)入睡眠狀態(tài),等待子進(jìn)程結(jié)束。一旦子進(jìn)程結(jié)束執(zhí)行,它會(huì)中止,釋放自己使用的內(nèi)存,并且喚醒父進(jìn)程,父進(jìn)程又可以準(zhǔn)備接受另外的命令請(qǐng)求,當(dāng)shell
提示符返回到屏幕上,你就知道子進(jìn)程已經(jīng)結(jié)束。
局部變量 和 環(huán)境變量
無(wú)論何時(shí)定義一個(gè)新的變量,它都會(huì)存儲(chǔ)在于與本進(jìn)程相聯(lián)系的局部數(shù)據(jù)空間中。如果一個(gè)子進(jìn)程想要存取這個(gè)變量,這個(gè)變量必須被傳送到環(huán)境中(使用export),一旦一個(gè)變量在環(huán)境中,它對(duì)每個(gè)后來(lái)的子進(jìn)程都會(huì)有效,,因?yàn)榄h(huán)境變量對(duì)每個(gè)子進(jìn)程都有效。
在上圖中,在vi 命令之前,color 變量在shell的局部數(shù)據(jù)空間里,TERM 變量在環(huán)境里。當(dāng)vi
命令執(zhí)行時(shí),shell執(zhí)行一次fork
和exec;子進(jìn)程的局部數(shù)據(jù)空間比子進(jìn)程的程序代碼所覆蓋,但環(huán)境被完整地傳遞給子進(jìn)程。因此,子進(jìn)程 vi 不能存取變量
color,但是它可以存取變量TERM。Vi
編輯器需要知道用戶的終端類型,用來(lái)適當(dāng)?shù)馗袷交妮敵。它通過(guò)讀取環(huán)境變量TERM的值來(lái)獲得這些信息。
唯一的傳遞數(shù)據(jù)給(子)進(jìn)程的方法是通過(guò)環(huán)境。
7.10 監(jiān)視進(jìn)程狀態(tài)
$ ps –f
UID PID PPID C STIME TTY TIME COMMNAD
user3 4702 1 1 08:46:40 ttyp4 0:00 -sh
user3 4895 4702 18 09:55:10 ttyp4 0:00 ps -f
$ ksh
$ ps –f
UID PID PPID C STIME TTY TIME COMMAND
user3 4702 1 0 08:46:40 ttyp4 0:00 -sh
user3 4896 4702 1 09:57:20 ttyp4 0:00 ksh
user3 4898 4896 18 09:57:26 ttyp4 0:00 ps –f
$exec ps –f
UID PID PPID C STIME TTY TIME COMMAND
user3 4702 1 0 08:46:40 ttyp4 0:00 -sh
user3 4896 4702 18 09:57:26 ttyp4 0:00 ps –f
$
系統(tǒng)中的每一個(gè)進(jìn)程在啟動(dòng)的時(shí)候都被賦予一個(gè)唯一的號(hào)碼,這個(gè)號(hào)碼被稱為進(jìn)程ID(PID)。Ps
命令顯示當(dāng)前在你系統(tǒng)中運(yùn)行(或睡眠)的進(jìn)程的信息,包括每個(gè)進(jìn)程的PID,每個(gè)進(jìn)程父進(jìn)程的PID(PPID)。通過(guò)PID
和PPID,你能夠追蹤你系統(tǒng)中任何進(jìn)程的體系。Ps命令同時(shí)也會(huì)報(bào)告每一個(gè)進(jìn)程的屬主,終端號(hào),和其他的有用的信息。
ps 命令通常不帶參數(shù)使用,結(jié)果是給出一個(gè)與你當(dāng)前終端對(duì)話相關(guān)的進(jìn)程的一個(gè)簡(jiǎn)單的報(bào)表,例如:
$ ps
PID TTY TIME COMMAND
ttyp4 0:00 sh
ttyp4 0:00 ps
正如你看到的那樣,這個(gè)命令顯示只有shell, sh,和 ps 命令正在運(yùn)行。注意兩個(gè)進(jìn)程的PID號(hào)碼。當(dāng)使用-f 選項(xiàng)時(shí)候,ps
命令給出一個(gè)全列表,包括PPID號(hào),我們可以看到ps –f
命令是作為shell的一個(gè)子進(jìn)程,因?yàn)樗腜PID號(hào)同shell的PID號(hào)是一致的。
請(qǐng)記住shell 同其他的UNIX命令一樣都是一個(gè)程序。如果你在當(dāng)前的POSIX shell 的提示符下使用ksh 命令,一個(gè)fork
和exec會(huì)執(zhí)行,一個(gè)Korn shell的子進(jìn)程回北創(chuàng)建,并開始執(zhí)行。當(dāng)我們執(zhí)行另一個(gè) ps –f 的時(shí)候,我們可以發(fā)現(xiàn),ksh
作為原shell,sh 的一個(gè)子進(jìn)程運(yùn)行,新的ps 命令作為Korn shell的一個(gè)子進(jìn)程。
exec命令是一個(gè)shell內(nèi)建的命令。如果用我們用 exec ps –f 來(lái)代替ps –f ,ps
的程序代碼會(huì)覆蓋當(dāng)前的進(jìn)程(ksh)的程序代碼。很明顯,這是因?yàn)閜s –f 的PID號(hào)與ksh 使用的PID是一致的。當(dāng)ps –f
結(jié)束后,我們會(huì)發(fā)現(xiàn)回到了最初的POSIX shell 提示符。
7.11 子進(jìn)程和環(huán)境
$ export color=lavender
$ ksh (創(chuàng)建一個(gè)子shell進(jìn)程)
$ ps -f
UID PID PPID C STIME TTY TIME COMMAND
user3 4702 1 0 08:46:40 ttyp4 0:00 -sh
user3 4896 4702 1 09:57:20 ttyp4 0:00 ksh
user3 4898 4896 18 09:57:26 ttyp4 0:00 ps –f
$ echo $color
lavender
$ color=red
$ echo $color
red
$ exit (退出子shell)
$ ps –f (回到父shell)
UID PID PPID C STIME TTY TIME COMMAND
user3 4702 1 0 08:46:40 ttyp4 0:00 -sh
user3 4895 4702 1 09:58:20 ttyp4 0:00 ps –f
$echo $color
lavender
上例說(shuō)明了子進(jìn)程不能夠更改它們的父進(jìn)程的環(huán)境。
$ ps –f
UID FSID PID PPID C STIME TTY TIME COMMAND
user3 default_system 4702 1 0 08:46:40 ttyp4 0;00 -sh
user3 default_system 4895 4702 1 09:58:20 ttyp4 0:00 ps –f
如果最初執(zhí)行一個(gè)ps –f 命令,它會(huì)顯示只有你的登錄shell(當(dāng)然還有ps )在運(yùn)行。如上表中,我們給一個(gè)變量color
賦值lavender,然后將這個(gè)變量傳遞到環(huán)境。下一步,我們執(zhí)行一個(gè)子進(jìn)程。執(zhí)行一個(gè)ksh命令,創(chuàng)建一個(gè)子Korn
shell進(jìn)程。當(dāng)然父進(jìn)程的環(huán)境已經(jīng)傳遞給這個(gè)子Korn
shell進(jìn)程,我們可以觀察到變量color的值是lavender。我們?nèi)缓蟾淖兞縞olor的值為red。echo命令確認(rèn)在子shell的環(huán)境中變量color的值已經(jīng)被改變。當(dāng)我們退出子shell回到父shell,我們發(fā)現(xiàn)富進(jìn)程的環(huán)境并沒(méi)有被子進(jìn)程改變,變量color仍然保持原來(lái)的值lavender.
本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u2/84425/showart_2069313.html |
|