linux學(xué)習 2009-01-13 16:44:50 閱讀30 評論0 字號:大中小 訂閱
我們從一個(gè)Shell腳本的內部執行兩種類(lèi)型的命令。也就是通常(normal)的命令,這樣的命令我們也可以在命令行的方式下來(lái)運行,稱(chēng)為處部命令,另 一種就是我們前面所說(shuō)的內建(built-in)命令,稱(chēng)之為內部命令。內建命令是在Shell的內部來(lái)實(shí)現的而不能為外部程序所調用。然而大多數的內部 命令也會(huì )作為相對獨立的單一程序來(lái)提供,而這也是POSIX 標準所要求的一部分。通常來(lái)說(shuō)內部命令與外部命令并沒(méi)有太大的區別,除非是這個(gè)內部運行得更為高效。
然而在這里我們只會(huì )討論一些主要的命令,包括我們編寫(xiě)一下腳本時(shí)所需要用到的外部與內部命令。作為一個(gè)Linux用戶(hù)我們會(huì )知道一些其他的可以在命令行來(lái)運行的命令。我們應該記住除了我們在這里所提到一些內建命令以后我們還可以在腳本中使用我們所知道的一些其他的命令。
break
當我們要從一個(gè)for,while或是until循環(huán)中退出時(shí)我們可以使用這個(gè)命令。我們也可以傳遞給break另外一個(gè)數字參數,而這個(gè)數字參數正是我 們要退出的循環(huán)次數。因為這樣會(huì )使得我們的腳本變得難于閱讀,所以我們并不推薦大家來(lái)使用這樣的方式。在默認的情況下,break只會(huì )退出單一的層次。如 下面的例子:
#!/bin/sh
rm -rf fred*
echo > fred1
echo > fred2
mkdir fred3
echo > fred4
for file in fred*
do
if [ -d “$file” ]; then
break;
fi
done
echo first directory starting fred was $file
rm -rf fred*
exit 0
:命令
冒號命令只是一個(gè)空命令。這個(gè)命令用來(lái)作為true的別名而簡(jiǎn)化邏輯條件是相當有用的。因為他是一個(gè)內建的命令,所以他運行得要比true快速,然而他的輸出卻并不是易于理解的。
我們可以看到在while循環(huán)中使用這個(gè)命令。while :可以替代更為常見(jiàn)的while true來(lái)實(shí)現無(wú)限的循環(huán)。
:結構在變量的設置條件中也是相當有用的,例如:
: ${var:=value}
如果沒(méi)有:,shell會(huì )試著(zhù)將$var作為一個(gè)命令來(lái)對待。
#!/bin/sh
rm -f fred
if [ -f fred ]; then
:
else
echo file fred did not exist
fi
exit 0
continue
與C語(yǔ)言相類(lèi)似,這個(gè)命令可以使得for,while,until中的變量使用列表中的下一個(gè)值繼續執行下一次循環(huán)。
#!/bin/sh
rm -rf fred*
echo > fred1
echo > fred2
mkdir fred3
echo > fred4
for file in fred*
do
if [ -d “$file” ]; then
echo “skipping directory $file”
continue
fi
echo file is $file
done
rm -rf fred*
exit 0
continue命令后可以跟一個(gè)用來(lái)作為一個(gè)可選參數的數字,這樣我們就可以部分的跳出嵌套循環(huán)。然而這樣的參數并不常用,因為這樣會(huì )使得我們的腳本難于理解。例如:
for x in 1 2 3
do
echo before $x
continue 1
echo after $x
done
這個(gè)腳本的輸出結果如下:
before 1
before 2
before 3
。命令
。命令會(huì )在當前的Shell中執行命令:
。 。/shell_script
通常情況下,當一個(gè)腳本執行一個(gè)外部的命令或是腳本時(shí),就會(huì )創(chuàng )建一個(gè)新的循環(huán)或是子Shell,這個(gè)外部命令會(huì )在新的環(huán)境下運行,然而這個(gè)新的環(huán)境就會(huì )無(wú)視返回給父Shell的返回代碼。但是外部的資源和。命令使得被調用腳本中所列出的命令在同一個(gè)環(huán)境下來(lái)運行。
這樣就意味著(zhù)在通常的情況下命令對環(huán)境變量所做的修改會(huì )丟失。而另一方面,。命令可以允許被執行的命令改變當前的運行循環(huán)。當我們要使用一個(gè)腳本作為包裝 來(lái)為后來(lái)一些其他命令的運行設置環(huán)境時(shí)是相當有用的。例如:如果我們同時(shí)在幾個(gè)不同的工程上進(jìn)行工作,有時(shí)我們就會(huì )發(fā)現我們需要使用一個(gè)不同的參數來(lái)調用 命令,也許是調用一個(gè)老版本的編譯器來(lái)維護一個(gè)古老的程序。
在Shell腳本中,。(dot)命令的工作方式與C或是C++中的#include的工作方式相類(lèi)似。雖然他并不真正包含一個(gè)腳本,但是他確實(shí)是在當前的條件下運行命令,所以我們可以使用這個(gè)命令在一個(gè)腳本中進(jìn)行變量或是函數定義的合并。
在下面的這個(gè)例子中,我們在命令行的方式下使用dot命令,但是我們也可以在一個(gè)腳本中使用這個(gè)命令。
1 假設我們有兩個(gè)文件,而這兩個(gè)文件所包含是為兩個(gè)不同的開(kāi)發(fā)環(huán)境所做的環(huán)境設置。要為古老的,經(jīng)典的命令設置環(huán)境,classic_set,我們可以使用下面的命令:
#!/bin/sh
version=classic
PATH=/usr/local/old_bin:/usr/bin:/bin:.
PS1=”classic> “
2而對于新的命令我們使用latest_set:
#!/bin/sh
version=latest
PATH=/usr/local/new_bin:/usr/bin:/bin:.
PS1=” latest version> “
我們可以使用dot命令將這些腳本進(jìn)行合并來(lái)設置環(huán)境,如下面的操作:
$ . ./classic_set
classic> echo $version
classic
classic> . latest_set
latest version> echo $version
latest
latest version>
echo
僅管在現代的Shell中使用printf命令,但是在這里我們仍然遵循通常的習慣來(lái)使用echo命令后跟新行字符的字符串。
一個(gè)通常的問(wèn)題就是如何來(lái)禁止一個(gè)新行字符。不幸的,不同版本的Unix實(shí)現了不同的解決方法。在Linux中通用的作法是:
echo -n “string to output”
但是也許我們常會(huì )看到下面的情況:
echo -e “string to output\c”
在第二種方法,echo -e確保允許解釋一些轉義字符,例如新\t解釋為tab,而將\n解釋為回車(chē)換行。這在通常的情況下是默認的設置
eval
eval命令允許我們進(jìn)行參數的賦值。他是Shell的內建命令而并不作為一個(gè)單獨的命令而存在。下面一個(gè)從X/Open所借用來(lái)的簡(jiǎn)短的例子可以很好的說(shuō)明這個(gè)問(wèn)題。
foo=10
x=foo
y=’$’$x
echo $y
這個(gè)例子的輸出結果為$foo,然而如果我們用下面的例子:
foo=10
x=foo
eval y=’$’$x
echo $y
這樣的輸出結果就為10.這樣eval就有一些像另外的一個(gè)$:他會(huì )提供給我們一個(gè)變量的值。
eval命令是非常有用的,他會(huì )允許我們隨時(shí)創(chuàng )建和運行代碼。他確實(shí)會(huì )將腳本的高度復雜化,但是他卻會(huì )允許我們做一些平常來(lái)說(shuō)非常困難甚到是不可能的事情。
exec
exec命令有兩種不同的用法。他最通常的用法是用一個(gè)不同的程序來(lái)替換當前的Shell。例如;
exec wall “Thanks for all the fish”
在腳本中會(huì )使用wall命令來(lái)替換當前的Shell。在exec命令之后的腳本內容不會(huì )處理,因為執行這個(gè)腳本的Shell已經(jīng)不存在了。
exec的第二種用法就是用來(lái)修改當前文件的描述符:
exec 3< afile
這個(gè)結果是是為了從文件afile文件中讀入內容而打開(kāi)文件描述符3.這樣有用法并不常見(jiàn)。
exit n
exit命令會(huì )使得腳本返回返回代碼。如果我們是在交互的Shell中運行這個(gè)命令,他就會(huì )使得我們退出會(huì )話(huà)。如果我們不指定我們的腳本不指定返回狀態(tài)而退出,那么腳本中上一次命令的執行結果就會(huì )作為返回值。通常指定返回值是一個(gè)很好的做法。
在Shell編程中,返回代碼0為成功,1到125是錯誤代碼,這些錯誤代碼可以為腳本所使用。保留的值具有保留的含義:
126 文件是不可執行的
127 命令沒(méi)有找到
128及以上 發(fā)生信號
使用0作為成功代碼在許多的C或是C++程序員看來(lái)會(huì )有一些的不同。這最大的優(yōu)點(diǎn)就是在腳本中允許我們使用125種用戶(hù)定義的錯誤代碼而不需要全局錯誤代碼變量。
在下面這個(gè)例子中,如果在當前的目錄下存在。profile文件就回成功值。
#!/bin/sh
if [ -f .profile ]; then
exit 0
fi
exit 1
如果我們是一個(gè)甘受懲罰的人或者是需要簡(jiǎn)潔的腳本,我們可以用我們在前面見(jiàn)過(guò)的AND和OR列表來(lái)重寫(xiě)我們的腳本,而將所有的內容放在一行:
[ -f .profile ] && exit 0 || exit 1
export
export命令可以使得變量以其子Shell中的參數進(jìn)行命令.在默認的情效況下,在一個(gè)Shell中所創(chuàng )建的變量在另一個(gè)所調用的Shell中并不是 可見(jiàn)的.export命令可以由他的參數創(chuàng )建一個(gè)環(huán)境變量,這個(gè)變量可以為當前程序中所調用的其他的腳本或是程序可見(jiàn).更為技術(shù)的一點(diǎn)來(lái)說(shuō),由任何子進(jìn)程 序所引進(jìn)的環(huán)境變量是由這個(gè)Shell派生的.這個(gè)命令的含義以及用法可以從下面的兩個(gè)腳本export1和export2來(lái)很好的進(jìn)行演示.
我們先列出export2的腳本內容:
#!/bin/sh
echo “$foo”
echo “$bar”
下面的是export1中的內容,在這個(gè)腳本的結尾處我們調用export2:
#!/bin/sh
foo=”The first meta-syntactic variable”
export bar=”The second meta-syntactic variable”
export2
如果我們運行這個(gè)腳本我們可以得到下面的結果:
$ export1
The second meta-syntactic variable
$
之所以發(fā)生第一行的空行是因為在export2中變量foo并不是可見(jiàn)的,所以$foo被賦值為空值,輸出一個(gè)空的變量就會(huì )得到一個(gè)新行.
一旦一個(gè)變量由一個(gè)Shell引入,那么他在由這個(gè)Shell中所派生的或是在這個(gè)Shell中所依次調用的腳本中都是可見(jiàn)的.如果腳本export2調用了另一個(gè)腳本,那么對于另一個(gè)腳本來(lái)說(shuō)這個(gè)變量的值仍然是可見(jiàn)的.
命令set -a或是set -allexport可以引入所有的變量.
expr
expr命令會(huì )將他的參數作為一個(gè)表達式來(lái)對待.他最常見(jiàn)的用法是用在如下面形式的簡(jiǎn)單算術(shù)中:
x=`expr $x + 1`
在這里的反引號(`)是將命令expr $x+1的結果作為變量x的值.我們也可以用語(yǔ)法$()來(lái)寫(xiě)這個(gè)句子而不使用反引號的形式,如下面的形式:
x=$(expr $x + 1)
expr命令是一個(gè)相當強大的命令,他可以處理許多表達賦值的問(wèn)題.他的一些原則如下表所示:
expr1 | expr2 如果expr1不為空則為expr1,否則為expr2
expr1 & expr2 如果expr2或是expr1為零則為零,否則為expr1
expr1 = expr2 相等
expr1 > expr2 大于
expr1 >= expr2 大于等于
expr1 < expr2 小于
expr1 <= expr2 小于等于
expr1 != expr2 不等于
expr1 + expr2 相加
expr1 - expr2 相減
expr1 * expr2 相乘
expr1 / expr2 整數相除
expr1 % expr2 整數取模
printf
printf命令只在現代的Shell中可用.X/Open建議我們最好應使用echo來(lái)產(chǎn)生格式化的輸出.
語(yǔ)法格式如下:
printf “format string” parameter1 parameter2 ...
字符串的格式與我們在C或是C++中所見(jiàn)到的相類(lèi)假,只是有一些限制.主要的區別在于Shell并支持浮點(diǎn)數,因為Shell中的所有算術(shù)運算都是作為整 數來(lái)處理的.格式化字符串可以由字母,轉義序列和轉義符的任何組合來(lái)構成.在格式化字符串中除了%和\的所有字符都可以進(jìn)行精確的輸出.
下面列出的是可以支持的轉義序列:
\\ 反斜線(xiàn)
\a 警告
\b 退格
\f 形成輸入字符
\n 新行字符
\r 回車(chē)
\t Tab字符
\v 垂直Tab
\ooo 由八進(jìn)制表示的單個(gè)字符
轉義字符是相當復雜的,所以我們在這里只是列出一些我們會(huì )常用到的內容.更為詳細的內容可以在在線(xiàn)的bash手冊中得到.轉義字符是%和緊跟其后的要轉義的字符組成的.下面列出一些主要的轉義字符:
d 輸出十進(jìn)制數
c 輸出一個(gè)字符
s 輸出一個(gè)字符串
% 輸出%字符
然后我們會(huì )使用格式化字符串來(lái)解釋其余的參數并進(jìn)行結果的輸出.例如:
$ printf “%s\n” hello
hello
$ printf “%s %d\t%s” “Hi There” 15 people
Hi There 15 people
在這里我們要注意我們必須使用""來(lái)使得Hi There字符串成為一個(gè)單一的參數.
return
return命令會(huì )使得一個(gè)函數返回.我們在前面的一些函數的用法中已經(jīng)注意到了這一點(diǎn).return命令會(huì )返回一個(gè)單一的數字參數,而這個(gè)數字參數在調用這個(gè)函數的腳本中是可見(jiàn)的.如果沒(méi)有指定返回參數,return在默認情況下會(huì )返回上一次命令的返回代碼.
set
set命令會(huì )為Shell設置參數變量.這對于在輸出由空格區分的命令中使用域是很有用的一個(gè)方法.
假如我們要在我們的Shell腳本中使用當前月份的名字.系統提供了一個(gè)日期的命令,這個(gè)命令含有字符串形式的月份,但是我們需要將他與其他的區域進(jìn)行分 離.我們可以使用set命令和$(...)結構的組合來(lái)執行日期命令并返回結果.日期命令的輸出是將月份的字符串作為他的第二個(gè)參數.
如下面的例子:
#!/bin/sh
echo the date is $(date)
set $(date)
echo The month is $2
exit 0
這個(gè)程序為date命令的輸出設置了參數列表,并且使用第二個(gè)參數$2來(lái)得到月份的名字.
在這里我們要注意的是我們使用date命令來(lái)作為一個(gè)簡(jiǎn)單的例子來(lái)展示如何解開(kāi)位置參數.因為date命令是與語(yǔ)言設置有關(guān)的,而事實(shí)上我們可以使用命令date +%B來(lái)得到月份的名字.date還有許多其他的格式選項,我們可以從他的手冊頁(yè)中得到更為詳細的說(shuō)明.
我們還可以使用set命令來(lái)控制通過(guò)傳遞Shell參數的Shell執行方式.這最通常的用法是使用命令set -x,這樣就會(huì )使得一個(gè)腳本顯示他當前執行命令的軌跡.
shift
shift命令可以使得所有的參數變量值減1,這樣$2就會(huì )變?yōu)?1,而$3就會(huì )變?yōu)?2,依次類(lèi)推.這樣以后$1的值就會(huì )丟棄,而$0的值會(huì )保持不變. 如果在調用shift命令時(shí)指定了一個(gè)數字參數,那么這些參數也會(huì )移動(dòng)一些相應的位置.而其他的一些變量,$*,$@,$#也會(huì )為新的參數變量的范圍進(jìn)行 相應的修改.
shift命令在參數之中進(jìn)行掃描是相當有用的,如果我們的腳本需要10個(gè)或是更多的參數,那么我們就需要使用shift來(lái)訪(fǎng)問(wèn)10個(gè)或是更多的內容.
作為例子,我們可以像下面的形式來(lái)掃描所有的位置參數:
#!/bin/sh
while [ “$1” != “” ]; do
echo “$1”
shift
done
exit 0
trap
trap命令可以用來(lái)指定在收到信號時(shí)所要進(jìn)行的動(dòng)作.一個(gè)常見(jiàn)的用法是在一個(gè)腳本被中斷時(shí)所做的處理工作.由于歷史的原因,Shell總是使用數字來(lái)代 表信號,但是新的腳本可以通過(guò)#include signal.h并且忽略SIG前綴來(lái)使用信號的名字.如果我們要查看信號的數字和其相關(guān)的名字我們可以在命令提示下輸入trap -l命令.
trap命令可以通過(guò)緊跟信號的名字的方式來(lái)傳遞將要進(jìn)行的動(dòng)作:
trap command signal
我們要記住通常情況下腳本是從上到下進(jìn)行解釋的,我們必須在我們要保護的腳本部分之前來(lái)指定trap命令.
要將一個(gè)trap的條件設置為默認的情況,我們可以簡(jiǎn)單的將命令指定為-.要忽略一個(gè)信號,我們可以將命令設為空串``.一個(gè)沒(méi)有任何參數的trap命令會(huì )打印出當前的動(dòng)作列表.
下面的表格列出了一些比較重要的標準的X/Open信號,這些信號都可以被捕獲.更為詳細的內容我們可以從信號手冊中得到.
HUP(1) 掛起.通常是當一個(gè)終端離線(xiàn)或是用戶(hù)退出時(shí)發(fā)出.
INT(2) 中斷.通常是通過(guò)按下Ctrl+C發(fā)出的.
QUIT(3) 退出,通常是由Ctrl+\發(fā)出的.
ABRT(6) 中止,通常是由一些嚴重的運行錯誤發(fā)出的.
ALRM(14) 警告.通常是由處理超時(shí)發(fā)出的.
TERM(15) 結束.通常是當系統關(guān)機時(shí)發(fā)出的.
下面的腳本模擬了一些簡(jiǎn)單信號的處理:
#!/bin/sh
trap ‘rm -f /tmp/my_tmp_file_$$’ INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo “press interrupt (CTRL-C) to interrupt ....”
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 1
done
echo The file no longer exists
trap INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo “press interrupt (control-C) to interrupt ....”
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 1
done
echo we never get here
exit 0
如果我們運行這個(gè)命令,我們在每一個(gè)循環(huán)中按下Ctrl+C,我們就會(huì )得到下面的輸出:
creating file /tmp/my_tmp_file_141
press interrupt (CTRL-C) to interrupt ....
File exists
File exists
File exists
File exists
The file no longer exists
creating file /tmp/my_tmp_file_141
press interrupt (CTRL-C) to interrupt ....
File exists
File exists
File exists
File exists
工作原理:
這個(gè)腳本使用trap命令來(lái)為命令rm -f /tmp/my_tmp_file_$$執行時(shí)接收到INT信號時(shí)安排將會(huì )執行的動(dòng)作.然后這個(gè)腳本會(huì )進(jìn)入一個(gè)循環(huán)直到文件存在.當用戶(hù)按下Ctrl+C 時(shí),語(yǔ)句rm -f /tmp/my_tmp_file_$$被執行,然后這個(gè)循環(huán)會(huì )重新開(kāi)始.因為這個(gè)文件已經(jīng)被刪除了,所以第一個(gè)while循環(huán)會(huì )正常的結束.
這個(gè)腳本然后會(huì )再一次使用trap命令,這一次是要指定當INT信號發(fā)生時(shí)沒(méi)有命令被執行.他會(huì )重新創(chuàng )建這個(gè)文件并進(jìn)入第二個(gè)循環(huán)語(yǔ)句.如果用戶(hù)在這時(shí)按 下Ctrl+C時(shí),沒(méi)有配置要執行的語(yǔ)句,所以會(huì )發(fā)生默認的動(dòng)作,即立即終止腳本.因為這個(gè)腳本是立即被終止的,所以最后的echo和exit命令并不會(huì ) 執行.
unset
unset命令會(huì )從當前的環(huán)境中移除變量或是函數.但是對于Shell自己定義的只讀的變量(例如IFS)不可以進(jìn)行這樣的操作.這個(gè)命令并不是經(jīng)常使用.
例如下面的這個(gè)例子:
#!/bin/sh
foo=”Hello World”
echo $foo
unset foo
echo $foo
兩個(gè)更為有用的命令和正則表達式
在我們開(kāi)始學(xué)習新的Shell編程知識之前,我們先來(lái)看一下兩個(gè)更為有用的兩個(gè)命令,這兩個(gè)命令雖然并不是Shell的一部分,但是在進(jìn)行Shell編程時(shí)卻會(huì )經(jīng)常用到.隨后我們會(huì )來(lái)看一下正則表達式.
find命令
我們先來(lái)看的是find命令.這個(gè)命令對于我們用來(lái)查找文件時(shí)是相當有用的,但是對于Linux新手來(lái)說(shuō)卻有一些難于使用,在一定程序是由于他所帶的選項,測試,動(dòng)作類(lèi)型參數,而且一個(gè)參數的執行結果會(huì )影響接下來(lái)的參數.
在我們深入這些選項和參數之前,我們先來(lái)看一個(gè)非常簡(jiǎn)單的例子.假如在我們的機子上有一個(gè)文件wish.我們來(lái)進(jìn)行這個(gè)操作時(shí)要以root身份來(lái)運行,這樣就可以保證我們可以搜索整個(gè)機子:
# find / -name wish -print
/usr/bin/wish
#
正如我們可以想到的,他會(huì )打印出搜索到的結果.很簡(jiǎn)單,是不是?
然而,他卻需要一定的時(shí)間來(lái)運行,因為他也會(huì )同時(shí)搜索網(wǎng)絡(luò )上的Window機器上的磁盤(pán).Linux機器會(huì )掛載大塊的Window機器的文件系統.他也會(huì )同時(shí)那些位置,雖然我們知道我們要查找的文件位于Linux機器上.
這也正是第一個(gè)選項的用武之地.如果我們指定了-mount選項,我們就可以告訴find命令不要搜索掛載的目錄.
# find / -mount -name wish -print
/usr/bin/wish
#
這樣我們仍然可以搜索這個(gè)文件,但是這一次并沒(méi)有搜索掛載的文件系統.
find命令的完整語(yǔ)法如下:
find [path] [options] [tests] [actions]
path是一個(gè)很簡(jiǎn)單的部分:我們可以使用絕對路徑,例如/bin,或者是使用相對路徑,例如.. .如果我們需要我們還可以指定多個(gè)路徑,例如 find /var /home
主要的一些選項如下:
-depth 在查看目錄本身以前要先搜索目錄中的內容
-follow 跟隨符號鏈接
-maxdepths N 在搜索一個(gè)目錄時(shí)至多搜索N層
-mount(或-xdev) 不要搜索其他的文件系統
下面的是一些test的選項.我們可以為find命令指定大量的測試,并且每一個(gè)測試會(huì )返回真或是假.當find命令工作時(shí),他會(huì )考查順序查找到的文件, 并且會(huì )在這個(gè)文件上按順序進(jìn)行他們所定義的測試.如果一個(gè)測試返回假,find命令會(huì )停止他當前正在考查的文件并繼續進(jìn)行下面的動(dòng)作.我們在下表中列出的 只是一些我們最常用到的測試,我們可以通過(guò)查看手冊頁(yè)得到我們可以利用find命令使用的可能的擴展列表項.
-atime N N天以前訪(fǎng)問(wèn)的文件
-mtime N N天以前修改的文件
-name pattern 除了路徑,與指定的類(lèi)型匹配的文件名.為了保證指定的類(lèi)型傳遞給find命令而并不是立即被Shell賦值,指定的類(lèi)型必須用引號進(jìn)行引用.
-newer otherfile 與otherfile文件相比要新的文件
-type C C類(lèi)型的文件,而這里的C可以指定的一種類(lèi)型.最常用的是d代表目錄,而f是指普通的文件.對于其他的文件類(lèi)型,我們可以查看手冊頁(yè).
-user username 指定的用戶(hù)所擁有的文件
我們也可以使用運算符進(jìn)行測試的組合.大多數的有兩種格式:短格式和長(cháng)格式.
! -not 測試的反
-a -and 所有的測試必須為真
-o -or 測試中某一個(gè)為真
我們可以使用括號來(lái)強行改變測試和運算符的次序.因為這些對于Shell來(lái)說(shuō)有著(zhù)特殊的意義,所以我們也需要使用反斜線(xiàn)將他們作為一個(gè)整體進(jìn)行引用.另 外,如果我們?yōu)槲募付似ヅ漕?lèi)型,我們也必須用引號進(jìn)行引用,這樣就可以避免他們被Shell進(jìn)行擴展,從而可以將他們直接傳遞給find命令.所以 如果我們要寫(xiě)一個(gè)這樣的測試,要查找比X文件要近或者是以一個(gè)范圍開(kāi)頭的文件,我們要寫(xiě)成下面的形式:
\(-newer X -o -name “_*” \)
現在我們要試著(zhù)在當前的目錄下查找最近修改日期比while2更近的文件,我們可以用下面的命令:
$ find . -newer while2 -print
.
./elif3
./words.txt
./words2.txt
./_trap
$
我們在上面所用的命令看起來(lái)似乎不錯,但是我們卻同時(shí)也搜索了當前的目錄文件,而這并不是我們所希望的,我們所感興趣只是常規文件.所以我們可以加上另外一個(gè)測試-type f:
$ find . -newer while2 -type f -print
./elif3
./words.txt
./words2.txt
./_trap
$
工作原理:
這些命令是如何進(jìn)行工作的呢?我們指定find命令應該在當前的目錄下進(jìn)行查找(.),而我們所要查找的是比while2更新的文件(-newer while2),而且如果已經(jīng)傳遞了測試,還要測試這個(gè)文件是否為一個(gè)常規文件(-type -f).最后,我們使用我們以前用過(guò)的動(dòng)作,-print,僅僅是來(lái)驗證我們所找到的文件.
下面我們要查找的文件或者是以下劃線(xiàn)開(kāi)頭的或者是要比while2文件新的文件,但是也必須為一個(gè)常規文件.這個(gè)例子可以向我們展示如何來(lái)進(jìn)行測試的組合:
$ find . \( -name “_*” -or -newer while2 \) -type f -print
./elif3
./words.txt
./words2.txt
./_break
./_if
./_set
./_shift
./_trap
./_unset
./_until
聯(lián)系客服