對話 UNIX _在 UNIX 中使用管道、重定向、操作_第1頁
對話 UNIX _在 UNIX 中使用管道、重定向、操作_第2頁
對話 UNIX _在 UNIX 中使用管道、重定向、操作_第3頁
對話 UNIX _在 UNIX 中使用管道、重定向、操作_第4頁
對話 UNIX _在 UNIX 中使用管道、重定向、操作_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、學(xué)習(xí)更多的命令行技巧和操作符更好地理解 UNIX® 用戶輸入的這些 “奇怪的” 字符。學(xué)習(xí)如何在 UNIX 中使用管道、重定向、操作符等特性。現(xiàn)在,您已經(jīng)在 IBM® AIX® 上工作了一段時間了。您已經(jīng)學(xué)習(xí)了幾個基本命令,能夠在目錄結(jié)構(gòu)中移動、創(chuàng)建和修改文件、查看正在運行的進程以及管理用戶和系統(tǒng)。這很不錯,但是您希望了解 UNIX® 管理員輸入的命令是什么意思。這些命令中包含許多奇怪的符號。在本文中,了解 |、>、>>、<、<<、 和  等符號在 UNIX 和 Linux

2、74; 中的意思,以及如何使用 &&、|、<、<= 和 != 操作符。管道如果您熟悉 UNIX,那么管道(或 pipe)會是每天都要接觸到的東西。管道最初是由 Malcolm McIlroy 開發(fā)的,可以使用管道把一個命令的標(biāo)準(zhǔn)輸出(stdout)定向到下一個命令的標(biāo)準(zhǔn)輸入(stdin),這樣就形成了連續(xù)執(zhí)行的命令鏈??梢栽谝粋€命令行上使用多個管道。在許多時候,一個命令的 stdout 用作下一個命令的 stdin,第二個命令的 stdout 又被重定向到另一個命令的 stdin,依此類推。例如,在排除故障或執(zhí)行日常

3、檢查時,大多數(shù) UNIX 管理員首先做的事情之一是查看系統(tǒng)上當(dāng)前正在運行的進程。清單 1 演示這樣的檢查。清單 1. 日常進程檢查示例# ps ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 Jul 27 - 0:05 /etc/init root 53442 151674 0 Jul 27 - 0:00 /usr/sbin/syslogd root 57426 1 0 Jul 27 - 0:00 /usr/lib/errdemon root 61510 1 0 Jul 27 - 23:55 /usr/sbin/syncd 60 roo

4、t 65634 1 0 Jul 27 - 0:00 /usr/ccs/bin/shlap64 root 82002 110652 0 Jul 27 - 0:24 /usr/lpp/X11/bin/X -x abx -x dbe -x GLX -D /usr/lib/X11/rgb -T -force :0 -auth /var/dt/A:0-SfIdMa root 86102 1 0 Jul 27 - 0:00 /usr/lib/methods/ssa_daemon -l ssa0 root 106538 151674 0 Jul 27 - 0:01 sendmail: accepting c

5、onnections root 110652 1 0 Jul 27 - 0:00 /usr/dt/bin/dtlogin -daemon root 114754 118854 0 Jul 27 - 20:22 dtgreet root 118854 110652 0 Jul 27 - 0:00 dtlogin <:0> -daemon root 131088 1 0 Jul 27 - 0:07 /usr/atria/etc/lockmgr -a /var/adm/atria/almd -q 1024 -u 256 -f 256 root 147584 1 0 Jul 27 - 0:

6、01 /usr/sbin/cron root 155816 151674 0 Jul 27 - 0:04 /usr/sbin/portmap root 163968 151674 0 Jul 27 - 0:00 /usr/sbin/qdaemon root 168018 151674 0 Jul 27 - 0:00 /usr/sbin/inetd root 172116 151674 0 Jul 27 - 0:03 /usr/sbin/xntpd root 180314 151674 0 Jul 27 - 0:19 /usr/sbin/snmpmibd root 184414 151674 0

7、 Jul 27 - 0:21 /usr/sbin/aixmibd root 188512 151674 0 Jul 27 - 0:20 /usr/sbin/hostmibd root 192608 151674 0 Jul 27 - 7:46 /usr/sbin/muxatmd root 196718 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.mountd root 200818 151674 0 Jul 27 - 0:00 /usr/sbin/biod 6 root 213108 151674 0 Jul 27 - 0:00 /usr/sbin/nfsd

8、3891 root 221304 245894 0 Jul 27 - 0:05 /bin/nsrexecd daemon 225402 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.statd root 229498 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.lockd root 241794 151674 0 Jul 27 - 0:51 /usr/lib/netsvc/yp/ypbind root 245894 1 0 Jul 27 - 0:00 /bin/nsrexecd root 253960 1 0 Jul 27 -

9、0:00 ./mflm_manager root 274568 151674 0 Jul 27 - 0:00 /usr/sbin/sshd -D root 282766 1 0 Jul 27 lft0 0:00 /usr/sbin/getty /dev/console root 290958 1 0 Jul 27 - 0:00 /usr/lpp/diagnostics/bin/diagd root 315646 151674 0 Jul 27 - 0:00 /usr/sbin/lpd root 319664 1 0 Jul 27 - 0:00 /usr/atria/etc/albd_serve

10、r root 340144 168018 0 12:34:56 - 0:00 rpc.ttdbserver 100083 1 root 376846 168018 0 Jul 30 - 0:00 rlogind cormany 409708 569522 0 19:29:27 pts/1 0:00 -ksh root 569522 168018 0 19:29:26 - 0:00 rlogind cormany 733188 409708 3 19:30:34 pts/1 0:00 ps -ef root 749668 168018 0 Jul 30 - 0:00 rlogind系統(tǒng)上當(dāng)前正在

11、運行的進程的列表可能像 清單 1 這么簡單;但是,大多數(shù)生產(chǎn)系統(tǒng)運行的進程更多,這會使 ps 的輸出更長。為了把這個列表縮短到自己需要的范圍,可以使用管道把 ps ef 的標(biāo)準(zhǔn)輸出重定向到 grep,從而搜索自己真正希望看到的結(jié)果。清單 2 把 清單 1 產(chǎn)生的進程列表重定向到 grep,搜索字符串 “rpc” 和 “ksh”。清單 2. 把進程列表重定向到 grep# ps ef | grep E "rpc|ksh" root 196718 151674 0 11

12、:00:27 - 0:00 /usr/sbin/rpc.mountd daemon 225402 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.statd root 229498 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.lockd root 340144 168018 0 12:34:56 - 0:00 rpc.ttdbserver 100083 1 cormany 409708 569522 0 19:29:27 pts/1 0:00 -ksh cormany 733202 409708 0 19:52:20 pts/1

13、0:00 grep -E rpc|ksh當(dāng)多次把 stdout 重定向到 stdin 時,管道的使用方法可以很復(fù)雜。在下面的示例中,擴展了前面的 ps 和 grep 示例,把它的 stdout 重定向到另一個 grep,其作用是排除包含 “grep” 或 “ttdbserver” 的字符串。當(dāng)最后的 grep 操作完成時,再次使用管道把 stdout 重定向到一個 awk 語句,其作用是輸出進程標(biāo)識符(PID)大于 200,000 的所有進程:# ps ef | grep E "rpc|ksh&

14、quot; | grep -vE "grep|rpc.ttdbserver" | awk -v _MAX_PID=200000 'if ($2 > _MAX_PID) print "PID for process",$8,"is greater than", _MAX_PID'PID for process /usr/sbin/rpc.statd is greater than 200000PID for process /usr/sbin/rpc.lockd is greater than 200000PID

15、for process -ksh is greater than 200000圖 1 通過圖形說明命令的 stdout 重定向到后續(xù)命令的 stdin 的次序。圖 1. 管道示例用 >、>>、< 和 << 執(zhí)行數(shù)據(jù)重定向通過命令行界面(CLI)執(zhí)行命令的另一個重要方面是,能夠把各種輸出寫到一個設(shè)備,或者把來自另一個設(shè)備的輸入讀取到命令中。要想寫一個命令的輸出,需要在執(zhí)行的命令后面加上大于號(> 或 >>)和所需的目標(biāo)文件名或設(shè)備。如果目標(biāo)文件不存在,而且您對目標(biāo)目錄有寫權(quán)限,那么 > 和 >> 會創(chuàng)建這個文件并根

16、據(jù)您的 umask 設(shè)置權(quán)限,然后把命令的輸出寫到剛創(chuàng)建的文件中。但是,如果這個文件存在,> 會嘗試打開文件并覆蓋整個內(nèi)容。如果希望在這個文件中追加內(nèi)容,那么只需使用 >>。可以認為它的作用是把左邊命令的輸出數(shù)據(jù)流移動到右邊的目標(biāo)文件中(即 <cmd> -> <output> -> <file>)。下面的示例執(zhí)行 “管道” 一節(jié)中的 ps ef 示例,并把輸出重定向到文件 ps_out:# ps ef | grep E "rpc|ksh&q

17、uot; > ps_out下面的代碼執(zhí)行前面擴展的管道示例并把輸出重定向到同一個文件(ps_out),但是追加到當(dāng)前數(shù)據(jù)后面:# ps ef | grep E "rpc|ksh" | grep -vE "grep|rpc.ttdbserver" | awk -v _MAX_PID=200000 'if ($2 > _MAX_PID) print "PID for process",$8,"is greater than", _MAX_PID' >> ps_out清單 3

18、60;給出前兩個重定向的輸出。清單 3. 重定向的輸出# cat ps_out root 196718 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.mountd daemon 225402 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.statd root 229498 151674 0 11:00:27 - 0:00 /usr/sbin/rpc.lockd root 340144 168018 0 12:34:56 - 0:00 rpc.ttdbserver 100083 1 cormany 409708 569522 0 1

19、9:29:27 pts/1 0:00 -ksh cormany 733202 409708 0 19:52:20 pts/1 0:00 grep -E rpc|kshPID for process /usr/sbin/rpc.statd is greater than 200000PID for process /usr/sbin/rpc.lockd is greater than 200000PID for process -ksh is greater than 200000當(dāng)只使用 > 重定向輸出時,只重定向命令的 stdout。但是,除了 stdout,還有

20、stderr 輸出:前者表示為 1,后者表示為 2。在 UNIX 中輸出重定向沒有區(qū)別。只需在 > 前面加上所需的輸出類型(例如,1>、2>),告訴 shell 要把輸出路由到哪里。清單 4 嘗試列出 fileA.tar.bz2 和 fileC.tar.bz2。但是,如第一個命令(ls)所示,fileC.tar.bz2 不存在。好在可以把 stdout 和 stderr 分別重定向到 ls.out 和 ls.err,這樣就能夠看到錯誤消息。清單 4. 列出文件 fileA.tar.bz2 和 fileC.tar.bz2# ls

21、fileA.tar.bz2 fileAA.tar.bz2 fileB.tar.bz2 fileBB.tar.bz2# ls fileA.tar.bz2 fileC.tar.bz2 1> ls.out 2> ls.err# cat ls.outfileA.tar.bz2# cat ls.errls: 0653-341 The file fileC.tar.bz2 does not exist.在 AIX 中,對 stdout 和 stderr 使用 > 和 >> 時應(yīng)用相同的規(guī)則。例如,以后的測試可以使用相同的輸出文件,見&#

22、160;清單 5。清單 5. 使用輸出文件進行以后的測試# ls fileB.tar.bz2 fileD.tar.bz2 1>> ls.out 2>> ls.err# cat ls.outfileA.tar.bz2fileB.tar.bz2# cat ls.errls: 0653-341 The file fileC.tar.bz2 does not exist.ls: 0653-341 The file fileD.tar.bz2 does not exist.有時候,可能需要把 stdout 和 stderr 寫到同一個文件或設(shè)備。這有兩種方法。第一種方法是把

23、60;1> 和 2> 重定向到同一個文件:# ls fileA.tar.bz2 fileC.tar.bz2 1> ls.out 2> ls.out# cat ls.outfileA.tar.bz2ls: 0653-341 The file fileC.tar.bz2 does not exist.第二個方法更簡單更快速,有經(jīng)驗的 UNIX 用戶更喜歡采用這種方法:# ls fileA.tar.bz2 fileC.tar.bz2 > ls.out 2>&1# cat ls.outfileA.tar.bz2ls: 0653-

24、341 The file fileC.tar.bz2 does not exist.我們分解這個語句。首先,執(zhí)行 ls fileA.tar.bz2 fileC.tar.bz2。然后使用 > ls.out 把 stdout 重定向到 ls.out,使用 2>&1 把 stderr 重定向到前面重定向的 stdout(ls.out)。請記住,可以把輸出重定向到文件和其他設(shè)備??梢园褦?shù)據(jù)重定向到打印機、軟盤、終端類型(TTY)以及各種其他設(shè)備。例如,如果希望把一個消息發(fā)送給所有會話(或 TTY)上的某個用戶,那么只需循環(huán)處理

25、60;who 并把一個消息重定向到 TTY(如果您有足夠的權(quán)限的話),見 清單 6。清單 6. 把消息重定向到一個 TTY# for _TTY in 'who | grep "cormany" | awk 'print $2''> do> _TTY="/dev/$_TTY"> echo "Sending message to cormany on $_TTY"> echo "Test Message to cormany$_TTY" >

26、; $_TTY> doneSending message to cormany on /dev/pts/13Test Message to cormany/dev/pts/13Sending message to cormany on /dev/pts/14stdin 而不是 stdout盡管使用 > 和 >> 對于大多數(shù)人是一個相當(dāng)容易掌握的概念,但是有的人在使用小于號(< 和 <<)時常常有困難。在考慮 > 和 >> 時,認為它們把左邊命令的輸出數(shù)據(jù)流移動到右邊的目標(biāo)文件中,這樣最容易理解。同樣的方法也適用于 < 和 <

27、;<。在使用 < 時,本質(zhì)上是用一個已經(jīng)提供的 stdin 執(zhí)行一個命令。也就是說,把已經(jīng)提供的數(shù)據(jù)提供給左邊的命令作為 stdin(即 <cmd> <- <data>)。例如,假設(shè)希望把一個包含 ASCII 文本文件的電子郵件發(fā)送給另一個用戶??梢允褂霉艿腊?#160;cat 的 stdout 重定向到 mail 的 stdin(即 cat mail_file.out | mail s "Here's your E-mail!" acormany),也可以把文件的

28、內(nèi)容重定向到 mail 命令的 stdin:# mail s "Here's your E-mail!" acormany < mail_file.out使用 <<(也稱為 here-document)可以節(jié)省格式化時間,并且使命令執(zhí)行的處理更容易。通過使用 <<,文本字符串被重定向到執(zhí)行的命令作為 stdin,但是可以繼續(xù)輸入信息,直到到達終止標(biāo)識符。只需輸入命令,輸入 << 和終止標(biāo)識符,然后輸入需要的任何內(nèi)容,最后在一個新行上輸入終止標(biāo)識符。通過使用 here-document,可以保留空

29、格、換行等。例如,UNIX 必須單獨處理下面五個 echo 語句:# echo "Line 1"Line 1# echo "Line 2"Line 2# echo "Line 3"Line 3# echo "Line 4"Line 4# echo "Line 5"Line 5可以用以下代碼替換多個 echo 語句,UNIX 只需處理一次執(zhí)行:# cat << EOF> Line 1> Line 2> Line 3> Li

30、ne 4> Line 5> EOFLine 1Line 2Line 3Line 4Line 5還可以使用制表符讓 shell 腳本中的內(nèi)容更整潔一點,這只需要在 << 和終止標(biāo)識符之間放上一個連字符(-):# cat <<- ATC>Line 1>Line 2>Line 3>Line 4>Line 5> ATCLine 1Line 2Line 3Line 4Line 5清單 7 給出的示例演示如何結(jié)合使用本文到目前為止討論的東西。清單 7. 組合 CLI# cat redirect_example#!/usr/b

31、in/kshcat <<- ATC | sed "s/Redirect Example => /g" >> atc.outThis is an example of how to redirectstdout to a file as well as pipe stdout into stdinof another command (i.e. sed), all done insidea here-document.Cool eh?ATC現(xiàn)在,看看關(guān)于重定向和管道的腳本。# ./redirect_example# cat atc.outRedi

32、rect Example => This is an example of how to redirectRedirect Example => stdout to a file as well as pipe stdout into stdinRedirect Example => of another command (i.e. sed), all done insideRedirect Example => a here-document.Redirect Example =>Redirect Example => Cool eh?回頁首子 shell

33、有時候,需要一起執(zhí)行幾個命令。例如,如果希望在另一個目錄中執(zhí)行某一操作,可以使用 清單 8 中的代碼。清單 8. 同時執(zhí)行幾個命令# pwd/home/cormany# cd testdir# tar cf ls_output.tar ls.out?# pwd/home/cormany/testdir這是有效的,但是要注意,在執(zhí)行這些步驟之后,您就不再位于原來的目錄中了。通過把這些命令放在它們自己的子 shell 中,它們會作為子 shell 的實例執(zhí)行。清單 9 演示如何使用子 shell 執(zhí)行相同的代碼。清單 9. 使用子 shell 同時執(zhí)行幾個命令# pw

34、d/home/cormany# (cd testdir ; tar -cf ls_output.tar ls.out?)# pwd/home/cormany回頁首test 命令、 和 在編寫 shell 腳本或用任何現(xiàn)代語言編寫程序時,運算表達式或值的能力都很重要。UNIX 一直通過 test 命令提供這一功能。正如 test 的手冊頁指出的,test 命令運算表達式參數(shù)的值,如果表達式的值是 True,就返回零(True)退出值。關(guān)于 test 的定義和所有可用條件的更多信息,請參見 test 手冊頁。

35、要想使用 test 命令,只需給這個命令提供適當(dāng)?shù)臉?biāo)志和文件名。當(dāng) test 運算完表達式時,返回到命令提示,可以在這里檢查返回碼,見 清單 10。清單 10. 檢查返回碼# ls l-rwxr-xr-x 1 cormany atc 786 Feb 22 16:11 check_file-rw-r-r- 1 cormany atc 0 Aug 04 20:57 emptyfile# test -f emptyfile# echo $?0# test -f badfilename# echo $?1根據(jù)定義,如果表達式值是 True,那么

36、0;test 返回零退出值,否則返回非零退出值(即 1)。在 清單 10 中,找到了文件 emptyfile,所以 test返回 0;但是沒有找到文件 badfilename,所以返回 1。使用 test 的另一種方法是把要運算的表達式放在單層方括號( )中。使用 test 命令或把它替換為   會返回相同的值:# -f emptyfile # echo $?0# -f badfilename # echo $?1使用單層方括號( )還是雙層方括

37、號( )是個人習(xí)慣問題,實際上取決于您如何學(xué)習(xí)命令和 shell 腳本編程。但是請記住,這兩者之間有一些差異。盡管   和   在運算期間使用相同的測試操作符,但是它們使用不同的邏輯操作符。回頁首操作符在 ksh(AIX 中使用的默認 shell)中,以及 UNIX 和 Linux 使用的其他 shell 中,一定要知道如何使用測試、邏輯和替換操作符。測試操作符在編寫 shell 腳本時,測試操作符對于檢查錯誤和檢查文件狀態(tài)很重要。下面只是可以在 ksh 和其他標(biāo)準(zhǔn) UNIX shell 中使用的一部分測試操作符:· -d <file&g

38、t;:<file> 是一個目錄· -e <flle>:<file> 存在· -f <file>:<file> 是一個常規(guī)文件· -n <string>:<string> 不是 NULL· -r <file>:用戶對 <file> 有讀權(quán)限· -s <file>:<file> 的大小大于 0· -w <file>:用戶對

39、60;<file> 有寫權(quán)限· -x <file>:用戶對 <file> 有執(zhí)行權(quán)限· -z <string>:<string> 是 null· -L <file>:<file> 是一個符號鏈接請記住,在 UNIX 目錄中,設(shè)備、符號鏈接和其他對象都是文件,所以上面的測試操作符適用于所有類型的文件。每個人都有自己的 shell 腳本編程風(fēng)格。無論在測試語句中使用   還是  ,上面的測試操作符的作用是相

40、同的。本文使用  。清單 11 演示如何使用上面列出的幾個測試操作符。清單 11. 使用測試操作符#!/usr/bin/kshwhile truedo echo "nEnter file to check: c" read _FNAME if ! -e "$_FNAME" then echo "Unable to find file '$_FNAME'" continue fi if -f "$_FNAME" then echo "$_FNAME is a file.&

41、quot; elif -d "$_FNAME" then echo "$_FNAME is a directory." elif -L "$_FNAME" then echo "$_FNAME is a symbolic link." else echo "Unable to determine file type for '$_FNAME'" fi -r "$_FNAME" && echo "User $USER can read

42、'$_FNAME'" -w "$_FNAME" && echo "User $USER can write to '$_FNAME'" -x "$_FNAME" && echo "User $USER can execute '$_FNAME'" if -s "$_FNAME" then echo "$_FNAME is NOT empty." else echo "$_FNA

43、ME is empty." fidone執(zhí)行清單 11 中的代碼并檢查幾個文件名,會產(chǎn)生 清單 12 所示的輸出。清單 12. 執(zhí)行測試操作符的輸出# ls l-rwxr-xr-x 1 cormany atc 786 Feb 22 16:11 check_file-rw-r-r- 1 cormany atc 0 Aug 04 20:57 emptyfile# ./check_fileEnter file to check: badfilenameUnable to find file 'badfilename'Enter file to check

44、: check_filecheck_file is a file.User cormany can read 'check_file'User cormany can write to 'check_file'User cormany can execute 'check_file'check_file is NOT empty.Enter file to check: emptyfileemptyfile is a file.User cormany can read 'emptyfile'User cormany can wr

45、ite to 'emptyfile'emptyfile is empty.要想了解關(guān)于測試操作符的更多信息和完整列表,請執(zhí)行 man test。邏輯操作符UNIX 中的另一組重要操作符是邏輯操作符。與大多數(shù)現(xiàn)代編程語言一樣,需要使用 AND 和 OR 語句對表達式或它們的值進行條件運算。如果您讀過我以前的文章(參見 參考資料),就會注意到我喜歡使用邏輯操作符,而不是編寫多行代碼。這會使腳本更干凈,更容易管理。在編寫腳本時,我會先編寫 exit_msg() 函數(shù):exit_msg() $# -gt 1

46、 && echo "$0#*/ ($1) $2" exit $1:-0這樣就不必編寫 清單 13 那樣臃腫的代碼。清單 13. 不使用 exit_msg() 函數(shù)和邏輯操作符的腳本#!/usr/bin/kshif -n $_NUM1 then unset _NUM1fiif -n $_NUM2 then unset _NUM2fiwhile -z $_NUM1 | -z $_NUM2 do echo "Enter 2 sets of numbers: c" read _NUM1 _NUM2doneecho "

47、Enter file to log results to: c"read _FNAMEif ! -e "$_FNAME" then echo "File '$_FNAME' doesn't exist. A new log will be created."fitouch "$_FNAME"if ! -w "$_FNAME" then echo "Unable to write to file '$_FNAME'" exit 1fiexpr $_

48、NUM1 / 1 > /dev/null 2>&1if $? -ne 0 then echo "Number '$_NUM1' is not numeric." exit 2fiexpr $_NUM2 / 1 > /dev/null 2>&1if $? -ne 0 then echo "Number '$_NUM2' is not numeric." exit 2fiecho "$_NUM1,$_NUM2" >> "$_FNAME"

49、只需使用 exit_msg() 這樣的簡單函數(shù)和幾個邏輯操作符,這個腳本就可以簡化成更漂亮更容易理解的程序,見 清單 14。清單 14. 使用函數(shù)和邏輯操作符的腳本簡化版本#!/usr/bin/kshexit_msg() $# -gt 1 && echo "$0#*/ ($1) - $2" exit $1:-0 -n $_NUM1 && unset _NUM1 -n $_NUM2 && unset _NUM2while -z $_NUM1 | -z $_NUM2 do echo "Ent

50、er 2 sets of numbers: c" read _NUM1 _NUM2doneecho "Enter file to log results to: c"read _FNAME ! -e "$_FNAME" && echo "File '$_FNAME' doesn't exist. A new log will be created."touch "$_FNAME" ! -w "$_FNAME" && exit_ms

51、g 1 "Unable to write to file '$_FNAME'"expr $_NUM1 / 1 > /dev/null 2>&1 $? -ne 0 && exit_msg 2 "Number '$_NUM1' is not numeric."expr $_NUM2 / 1 > /dev/null 2>&1 $? -ne 0 && exit_msg 2 "Number '$_NUM2' is not numeric

52、."echo "$_NUM1,$_NUM2" >> "$_FNAME"前面的示例主要使用 AND(&&)和 OR(|)邏輯操作符。除了這些之外,還可以使用 AND(a)和 OR(o)操作符。在使用 test 命令或單層方括號( )時,使用 a 和 o 運算表達式。但是,如果使用雙層方括號( ),就要使用 && 和 |:# "Paul" != "

53、Xander" && 2 -gt 0 # echo $?0# "Paul" != "Xander" -a 2 -gt 0 # echo $?0比較測試操作符另一組測試操作符稱為比較測試操作符。與前一組測試操作符一樣,比較測試操作符是執(zhí)行錯誤檢查或根據(jù)另一個值測試值的簡便方法。前一組測試操作符主要用來測試文件或檢查一個變量是否已經(jīng)定義了,而比較測試操作符主要用來測試字符串和數(shù)字值,例如檢查日期、檢查文件大小、檢查兩個字符串是否相同等等。比較測試操作符包括:· <fileA> -nt <fileB>

54、:fileA 比 fileB 新· <fileA> -ot <fileB>:fileA 比 fileB 舊· <fileA> -ef <fileB>:fileA 和 fileB 指向同一個文件· <string> = <pattern>:字符串與模式匹配· <string> != <pattern>:字符串與模式不匹配· <stringA> < <stringB>:按照詞典次序 stringA 出現(xiàn)在 stringB 之

55、前· <stringA> > <stringB>:按照詞典次序 stringA 出現(xiàn)在 stringB 之后· <exprA> -eq <exprB>:expressionA 等于 expressionB· <exprA> -ne <exprB>:expressionA 不等于 expressionB· <exprA> -lt <exprB>:expressionA 小于 expressionB· <exprA> -gt <e

56、xprB>:expressionA 大于 expressionB· <exprA> -le <exprB>:expressionA 小于或等于 expressionB· <exprA> -ge <exprB>:expressionA 大于或等于 expressionB可以按照與其他操作符相同的格式使用比較測試操作符??梢允褂?#160;test、  或  。清單 15、清單 16 和 清單 17 分別演示如何使用文件、數(shù)字和字符串比較。清單 15. 文件比較# ls -l

57、 *.file-rw-r-r- 1 cormany atc 21 Feb 22 2006 Pauls.file-rw-r-r- 1 cormany atc 22 Aug 04 20:57 Xanders.file# "Pauls.file" -ot "Xanders.file" # echo $?0清單 16. 數(shù)字比較# _PSIZE=ls -l Pauls.file | awk 'print $5'# _XSIZE=ls -l Xanders.file | awk 'print $5'# $_PSIZE -lt $_X

58、SIZE # echo $?0清單 17. 字符串比較# "cat" = "dog" # echo $?1替換操作符在編寫腳本時,很容易忘記定義一個變量或為它賦值?;蛘撸脦啄隂]有改動一個腳本,現(xiàn)在需要修改它,但是忘了它的細節(jié)。有時候,希望告訴用戶已經(jīng)設(shè)置了一個值,或者設(shè)置了某些默認值。替換操作符是解決這些問題的好方法:· $var-value:如果 <var> 存在,就返回 <var> 的值。如果 <var> 不存在,就返回 <v

59、alue>。· $var=value:如果 <var> 存在,就返回 <var> 的值。如果 <var> 不存在,就把 <var> 設(shè)置為 <value> 并返回 <value>。· $var+value:如果 <var> 存在,就返回 <var> 的值。如果 <var> 不存在,就返回 NUL

60、L。· $var?value:如果 <var> 存在,就返回 <var> 的值。如果 <var> 不存在,就退出命令或腳本并顯示用 <value> 設(shè)置的錯誤消息。如果未設(shè)置 <value>,就顯示默認的錯誤消息 “Parameter null or not set”。· $var:-value:如果 <var> 存在且不是 NULL,就返回 <var> 的值。如

61、果 <var> 不存在或者是 NULL,就返回 <value>。· $var:=value:如果 <var> 存在且不是 NULL,就返回 <var> 的值。如果 <var> 不存在或者是 NULL,就把 <var> 設(shè)置為 <value> 并返回 <value>。· $var:+value:如果 <var> 

62、存在且不是 NULL,就返回 <var> 的值。如果 <var> 不存在或者是 NULL,就返回 NULL。· $var:?value:如果 <var> 存在且不是 NULL,就返回 <var> 的值。如果 <var> 不存在或者是 NULL,就退出命令或腳本并顯示用<value> 設(shè)置的錯誤消息。如果未設(shè)置 <value>,就顯示默認的錯誤消息 “Parameter null or not set”。請注意前四個和后四個定義之間的細微差異。后一組定義在變量名和替換操作符之間包含一個冒號(:),這會額外檢查變量是否是 NULL。在考慮用替換操作符給變量賦值時,要注意的另一個重要問題是,給變量賦值應(yīng)用的規(guī)則與以一般方式從命令行或腳本定義變量的規(guī)則相同。不能用新值覆蓋受保護的保留變量(例如,$1、$2、$3)。清單 18 中的示例演示替換操作符的使用方法。注意,可以組

溫馨提示

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

評論

0/150

提交評論