国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

對(duì)話 UNIX,第 6 部分: 通過腳本實(shí)現(xiàn)操作的自動(dòng)化

瀏覽:22日期:2024-06-18 15:32:13

下面是簡(jiǎn)介:

如果您曾經(jīng)在資深 Unix® 用戶工作時(shí)站在他的背后注視屏幕,可能會(huì)對(duì)命令行上不斷滾動(dòng)的咒語(yǔ)般的奇怪內(nèi)容感到相當(dāng)迷惑。如果您閱讀過對(duì)話 UNIX 系列中以前的文章(請(qǐng)參見參考資料),那么至少所輸入的某些詩(shī)一般的神秘內(nèi)容——如波形符 (~)、管道 (|)、變量和重定向(< 和 >)——看起來(lái)是熟悉的。您也許還會(huì)認(rèn)出某些 UNIX 命令名稱和組合,或者了解何時(shí)使用別名來(lái)作為某個(gè)命令組合的簡(jiǎn)寫形式。

盡管如此,還有其他命令組合可能是您無(wú)法理解的,因?yàn)橘Y深的 UNIX 用戶通常以 Shell 腳本 的形式收集一大堆小的、高度專門化的命令組合,以簡(jiǎn)化或自動(dòng)化經(jīng)常重復(fù)的任務(wù)。與輸入或重新輸入(可能)復(fù)雜的命令來(lái)完成某個(gè)繁瑣任務(wù)不同,Shell 腳本可以自動(dòng)化該工作。

在對(duì)話 UNIX 系列(請(qǐng)參見參考資料)的第 6 部分中,您將學(xué)習(xí)如何編寫 Shell 腳本和更多命令行訣竅。

核心就是一個(gè)詞:“自動(dòng)化

有些 Shell 腳本完全就是反復(fù)運(yùn)行同樣的命令,并處理同樣的一組文件。例如,將您的整個(gè)主目錄內(nèi)容傳播到三臺(tái)遠(yuǎn)程計(jì)算機(jī)的 Z Shell 腳本可以像清單 1 一樣簡(jiǎn)單。

清單 1. 跨多臺(tái)計(jì)算機(jī)同步主目錄的簡(jiǎn)單 Shell 腳本

#! /bin/zshfor each Machine (groucho chico harpo)rsync -e ssh --times --perms --recursive --delete $HOME $machine:end

若要將清單 1 用作 Shell 腳本,可以將上述內(nèi)容保存到某個(gè)文件——例如 simpleprop.zsh——并運(yùn)行 chmod +x simpleprop.zsh 以使該文件成為可執(zhí)行文件。您可以通過輸入 ./simpleprop.zsh 來(lái)運(yùn)行該腳本。

如果您想查看 Z Shell 如何展開每個(gè)命令,可以將 -x 選項(xiàng)添加到腳本的 #!(# 號(hào)-感嘆號(hào)對(duì)通常稱為 shuh-bang)行的結(jié)尾,如下所示:

#! /bin/zsh -x

該腳本對(duì) groucho、chico 和 harpo 中的每一臺(tái)計(jì)算機(jī)運(yùn)行 rsync 命令,并將 $HOME 替換為您的主目錄(例如,/home/joe),將 $Machine 替換為計(jì)算機(jī)名稱。

如清單 1 所示,變量和諸如循環(huán)等腳本控制結(jié)構(gòu)使腳本更容易編寫和維護(hù)。如果您想將第四臺(tái)計(jì)算機(jī)(例如 zeppo)包括到計(jì)算機(jī)池中,只需將其添加到該列表。如果您必須更改 rsync 命令,比如說(shuō)添加另一個(gè)選項(xiàng),則只需編輯一個(gè)實(shí)例。與在傳統(tǒng)編程中一樣,您也應(yīng)該努力避免在 Shell 腳本中進(jìn)行剪切和粘貼。

使用恰當(dāng)?shù)膮?shù)

其他 Shell 腳本需要參數(shù),或要處理的對(duì)象——文件、目錄、計(jì)算機(jī)名稱——的動(dòng)態(tài)列表。例如,考慮清單 2,這是前一示例的變體,它允許您使用命令行來(lái)指定您想要與之同步的計(jì)算機(jī)。

清單 2. 允許您指定要處理的計(jì)算機(jī)的清單 1 的變體

#! /bin/zshfor each machinersync -e ssh --times --perms --recursive --delete $HOME $machine:end

假設(shè)您將清單 2 保存在名為 synch.zsh 的文件中,您得按照 zsh synch.zsh moe larry curly 的形式調(diào)用該腳本,以將主目錄復(fù)制到另外的計(jì)算機(jī) larry 和 curly。

foreach 行上缺少的列表并不是輸入錯(cuò)誤:如果您省略某個(gè)列表,則 foreach 結(jié)構(gòu)將處理命令行上給出的參數(shù)列表。命令行參數(shù)也稱為位置參數(shù) (positional parameter),因?yàn)槟硞€(gè)參數(shù)在命令行上的位置通常在語(yǔ)義上非常重要。

例如,如果您未 指定任何參數(shù),則 清單 2 可以利用位置參數(shù)的存在性或非存在性來(lái)提供有幫助的用法信息。增強(qiáng)的腳本如清單 3 所示。

清單 3. 許多腳本將在未提供參數(shù)時(shí)提供有幫助的消息

#! /bin/zshif [[ -z $1 || $1 == "--help" ]]thenecho "usage: $0 Machine [machine ...]fiforeach machinersync -e ssh --times --perms --recursive --delete $HOME $machine:end

命令行上的每個(gè)空格分隔的字符串變成了位置參數(shù),包括所調(diào)用的腳本的名稱。因此,命令 synch.zsh 只有一個(gè)位置參數(shù) $0。synch.zsh --help 命令有兩個(gè)位置參數(shù):$0 和 $1,其中 $1 是字符串 --help。

所以,清單 3 表示“如果第一個(gè)位置參數(shù)為空(-z 操作符測(cè)試空字符串)或(由 || 表示)如果第一個(gè)參數(shù)等于‘—help’,則打印用法信息。(如果您剛開始編寫腳本,可以考慮在每個(gè)腳本中提供用法信息作為提示。它提醒其他人——甚至您自己,如果您忘了的話——如何使用該腳本。)

短語(yǔ) [[ -z $1 || $1 == "--help" ]] 是 if 語(yǔ)句的 條件,但您也可以將同樣的條件子句用作命令,并將其與其他命令組合使用以控制通過腳本的流。請(qǐng)查看清單 4。它枚舉您的 $PATH 中的所有可執(zhí)行命令,并將條件與其他命令組合使用以執(zhí)行適當(dāng)?shù)墓ぷ鳌?/p>

清單 4. 列出 $PATH 中的命令

#! /bin/zshDirectorIEs=(`echo $PATH | column -s ':' -t`)for directory in $directoriesdo [[ -d $directory ]] || continue  pushd "$directory"  for file in * do [[ -x $file && ! -d $file ]] || continue echo $file done  popddone | sort | uniq

此腳本中執(zhí)行了相當(dāng)多的操作,我們將它細(xì)分為以下幾部分:

第一個(gè)實(shí)際腳本行——DirectorIEs=(`echo $PATH | column -s ':' -t`)——創(chuàng)建指定目錄的數(shù)組。您在 zsh 中通過將參數(shù)放在括號(hào)中來(lái)創(chuàng)建數(shù)據(jù),例如 directories=(...)。在此例中,數(shù)組元素是通過在每個(gè)冒號(hào)(column -s ':')處分拆 $PATH 以產(chǎn)生空格分隔的目錄列表(column 的 -t 參數(shù))來(lái)生成的。

對(duì)于列表中的每個(gè)目錄,該腳本嘗試枚舉該目錄中的可執(zhí)行文件。步驟 3 至步驟 6 描述了該過程。

[[ -d $directory ]] || continue 行是所謂的 short-circuiting 命令的一個(gè)示例。short-circuiting 命令在其邏輯條件產(chǎn)生確定的結(jié)果時(shí)立即終止。

例如,[[ -d $directory ]] || continue 短語(yǔ)使用邏輯“或(||)——它首先執(zhí)行第一個(gè)命令,并且——當(dāng)且僅當(dāng)——第一個(gè)命令失敗時(shí)才執(zhí)行第二個(gè)命令。因此,如果 $directory 中的條目存在,并且是一個(gè)目錄(-d 操作符),則測(cè)試成功,求值結(jié)束,并且 continue 命令(它跳過當(dāng)前元素的處理)永遠(yuǎn)不會(huì)執(zhí)行。

然而,如果第一個(gè)測(cè)試失敗,則會(huì)執(zhí)行該邏輯的下一個(gè)條件或執(zhí)行 continue。(continue 始終成功,因此它通常出現(xiàn)在 short-circuiting 命令的最后)。

基于邏輯“與(&&) 的 Short-circuiting 首先執(zhí)行第一個(gè)命令,并且——當(dāng)且僅當(dāng)——第一個(gè)命令成功時(shí)才執(zhí)行第二個(gè)命令。

pushd 和對(duì)應(yīng)的 popd 分別用于在處理前切換到新目錄和在處理后切換到先前的目錄。使用目錄堆棧是一種理想的腳本技術(shù),用于維持您在文件系統(tǒng)中的位置。

內(nèi)部的 for 循環(huán)枚舉當(dāng)前工作目錄中的所有文件——通配符 *(星號(hào))匹配所有條目——然后測(cè)試每個(gè)條目是否為文件。[[ -x $file && ! -d $file ]] || continue 行表示“如果 $file 存在并且是可執(zhí)行文件而且不是目錄,則處理它;否則執(zhí)行 continue。

最后,如果前面的所有條件都滿足,則使用 echo 來(lái)顯示文件名。

您弄明白該腳本的最后一行了嗎?您可以將大多數(shù)控制結(jié)構(gòu)的輸出發(fā)送給另一個(gè) Unix 命令——畢竟,Shell 將該控制結(jié)構(gòu)視為一個(gè)命令。因此,整個(gè)腳本的輸出通過 sort、然后通過 uniq 進(jìn)行管道傳輸,以產(chǎn)生在您的 $PATH 中找到的唯一命令的字母排序列表。

如果將清單 4 保存到一個(gè)名為 listcmds.zsh 的可執(zhí)行文件,則輸出可能類似如下:

$ ./listcmds.zsh[a2pabacacceptacctonaclocal

short-circuiting 命令在腳本中非常有用。它在單個(gè)命令中組合了條件和操作。而且由于每個(gè) UNIX 命令都返回一個(gè)指示成功或失敗的狀態(tài)代碼,因此,您可以使用任何命令作為“條件——而不僅僅是使用測(cè)試操作符。根據(jù)約定,UNIX 返回零 (0) 表示成功,返回非零表示失敗,其中非零值反映所發(fā)生的錯(cuò)誤類型。

例如,如果將 [[ -d $Directory ]] || continue 行替換為 cd $directory || continue,則可以從清單 4 中消除 pushd 和 popd。如果 cd 命令成功,則它會(huì)返回 0,并且邏輯“或的求值可以立即結(jié)束。然而,如果 cd 失敗,則它會(huì)返回非零,并且會(huì)執(zhí)行 continue。

不要?jiǎng)h除。應(yīng)存檔!

現(xiàn)代 UNIX Shell——bash、ksh、zsh——提供了許多控制結(jié)構(gòu)和操作以創(chuàng)建復(fù)雜的腳本。由于您可以調(diào)用所有 UNIX 命令來(lái)將數(shù)據(jù)從一種形式處理為另一種形式,Shell 腳本編程幾乎與諸如 C 或 Perl 等完整語(yǔ)言中的編程一樣豐富。

您可以使用腳本來(lái)自動(dòng)化幾乎所有個(gè)人或系統(tǒng)任務(wù)。腳本可以監(jiān)視、存檔、更新、上載、下載和轉(zhuǎn)換數(shù)據(jù)。一個(gè)腳本可以只有單行或包括無(wú)數(shù)個(gè)子系統(tǒng)。任務(wù)無(wú)論大小,均可通過腳本來(lái)處理。實(shí)際上,如果您查看 /etc/init.d 目錄,會(huì)看到在每次啟動(dòng)計(jì)算機(jī)時(shí)運(yùn)行服務(wù)的各種 Shell 腳本。如果您創(chuàng)建了一個(gè)非常有用的腳本,您甚至可以將它部署為系統(tǒng)范圍的實(shí)用程序。只需將其放到用戶的 $PATH 上的某個(gè)目錄中。

讓我們創(chuàng)建一個(gè)實(shí)用程序,以練習(xí)您新發(fā)現(xiàn)的訣竅。腳本 myrm 將替換系統(tǒng)自己的 rm 實(shí)用程序。與徹底刪除某個(gè)文件不同,myrm 把要?jiǎng)h除的文件復(fù)制到某個(gè)存檔,對(duì)其進(jìn)行唯一命名以便您以后能夠找到它,然后再刪除原始文件。myrm 腳本有效但是非常簡(jiǎn)單,并且您還可以添加許多雜項(xiàng)功能。您還可以編寫一個(gè)廣泛的 unrm(撤銷刪除)腳本作為配套實(shí)用程序。(您可以搜索 Internet 來(lái)找到各種各樣的實(shí)現(xiàn)。)

myrm 腳本如清單 5 所示。

清單 5. 用于在從文件系統(tǒng)中刪除文件之前備份該文件的簡(jiǎn)單實(shí)用程序

#! /bin/zshbackupdir=$HOME/.tombsystemrm=/bin/rmif [[ -z $1 || $1 == "--help" ]]then exec $systemrmfiif [[ ! -d $backupdir ]]then mkdir -m 0700 $backupdir || echo "$0: Cannot create $backupdir"exitfiargs$=$( getopt dfiPRrvw $* ) || exec $systemrmcount=0flags = ""foreach argument in $argsdo case $argument in--) break;;; *) flags="$flags $argument";(( count=$count + 1 ));;; esacdoneshift $(( $count ))for filedo [[ -e $file ]] || continue copyfile=$backupdir/$(basename $file).$(date "+%m.%d.%y.%H.%M.%S") /bin/cp -R $file $copyfiledoneexec $systemrm $=flags "$@"

您應(yīng)該發(fā)現(xiàn)該 Shell 腳本很容易理解,盡管其中存在一些之前尚未討論過的新內(nèi)容。讓我們探討一下那些新內(nèi)容,然后查看整個(gè)腳本。

當(dāng) Shell 運(yùn)行某個(gè)命令(如 cp 或 ls)時(shí),它會(huì)為該命令產(chǎn)生一個(gè)新進(jìn)程,然后在繼續(xù)之前等待該(子)進(jìn)程完成。exec 命令還啟動(dòng)另外一個(gè)命令,但是與產(chǎn)生新進(jìn)程不同,exec 使用一個(gè)新命令來(lái)“替換當(dāng)前進(jìn)程——即 Shell 進(jìn)程——的任務(wù)。換句話說(shuō),exec 重用同一進(jìn)程來(lái)啟動(dòng)一個(gè)新任務(wù)。在該腳本的上下文中,exec 立即“終止該腳本并啟動(dòng)指定的任務(wù)。

Unix 實(shí)用程序 getopt 掃描位置參數(shù)以獲得您指定的命名參數(shù)。這里,dfiPRrvw 列表查找 -d、-f、-i、-P、-R、-r、-v 和 -w。如果出現(xiàn)別的選項(xiàng),則 getopt 將會(huì)失敗。否則,getopt 返回一個(gè)以特殊字符串 -- 結(jié)尾的選項(xiàng)字符串。

shift 命令從左到右刪除位置參數(shù)。例如,如果命令行為 myrm, -r -f -P file1 file2 file3,則 shift 3 將分別刪除 $0、$1 和 $2,或 -r、-f 和 -P。file1、file2 和 file3 將被重新編號(hào)為 $0、$1 和 $2。

case 語(yǔ)句的工作方式與傳統(tǒng)編程語(yǔ)言中的對(duì)應(yīng)結(jié)構(gòu)相似。它將其參數(shù)與列表中的每個(gè)模式比較;當(dāng)找到匹配項(xiàng)時(shí),則執(zhí)行對(duì)應(yīng)的代碼。與在 Shell 中非常類似,* 匹配所有條目,并且可用作在未找到其他匹配項(xiàng)時(shí)的缺省操作。

特殊符號(hào) $@ 展開為所有(其余)的位置參數(shù)。

zsh 操作符 $= 在空白邊界處拆分單詞。當(dāng)您有一個(gè)非常長(zhǎng)的字符串,并且希望將該字符串拆分為各個(gè)參數(shù)時(shí),$= 是非常有用的。例如,如果變量 x 包含字符串 '-r -f'——這是一個(gè)具有五個(gè)字符的單詞——$=x 將變?yōu)閮蓚€(gè)單獨(dú)的單詞 -r 和 -f。

給出這些解釋之后,您現(xiàn)在應(yīng)該能夠詳細(xì)分析該腳本了。下面讓我們逐塊地研究一下該代碼:

第一個(gè)塊設(shè)置整個(gè)腳本中使用的變量。

下一個(gè)塊應(yīng)該是非常熟悉的:它在未提供參數(shù)時(shí)打印用法信息。它為什么執(zhí)行 (exec) 實(shí)際的 rm 實(shí)用程序呢?如果您將此腳本命名為“rm并將其放在 $PATH 中靠前的位置,則它就可以充當(dāng) /bin/rm 的替代者。該腳本的錯(cuò)誤選項(xiàng)也是 /bin/rm 的錯(cuò)誤選項(xiàng),因此該腳本允許 /bin/rm 提供用法信息。

下一個(gè)塊在備份目錄不存在時(shí)創(chuàng)建該目錄。如果 mkdir 失敗,則該腳本終止并顯示適當(dāng)?shù)腻e(cuò)誤消息。

下一個(gè)塊查找位置參數(shù)列表中的 dash 參數(shù)。如果 getopt 成功,則 $args 具有一個(gè)選項(xiàng)列表。如果 getopt 失敗,例如在它無(wú)法識(shí)別某個(gè)選項(xiàng)的時(shí)候,則它會(huì)打印錯(cuò)誤消息,并且該腳本將退出并顯示用法信息。

隨后的塊捕獲一個(gè)字符串中旨在提供給 rm 的所有選項(xiàng)。當(dāng)遇到特殊 getopt 選項(xiàng) -- 時(shí),選項(xiàng)收集過程停止。shift 從參數(shù)列表中刪除所有已處理的參數(shù),保留待處理的文件和目錄列表。

從以 for file 開頭的塊復(fù)制每個(gè)文件和目錄,以便在您自己的存檔目錄中保存它們。每個(gè)文件的目錄被逐字 (-R) 復(fù)制到存檔目錄,并附帶當(dāng)前日期和時(shí)間作為后綴,以確保該副本是唯一的,并且不會(huì)改寫以前存檔的具有相同名稱的條目。

最后,使用傳遞給該腳本的相同命令行選項(xiàng)來(lái)刪除文件和目錄。

然而,如果您碰巧需要?jiǎng)偛艅h除(意外刪除?)的文件或目錄,您可以在存檔中查找原始副本。

向自動(dòng)化進(jìn)軍

您使用 Unix 的時(shí)間越多,就越有可能創(chuàng)建腳本。腳本可以節(jié)省重新輸入復(fù)雜的較長(zhǎng)命令序列所需的時(shí)間和精力,并且還可以防止發(fā)生錯(cuò)誤。Web 上充滿了其他人已創(chuàng)建的用于許多目的的有用腳本。很快您也會(huì)發(fā)布自己的神奇腳本。

標(biāo)簽: Unix系統(tǒng)
相關(guān)文章:
主站蜘蛛池模板: 99精品久久99久久久久久 | 国产日韩欧美精品在线 | 一级毛片一级毛片一级毛片 | caoporen免费公开视频上传 | 特及毛片 | 深夜福利视频在线观看免费播放 | 亚洲精品亚洲人成毛片不卡 | 国产精品毛片无码 | 久久九九免费视频 | 在线亚洲成人 | 亚洲欧美94色 | 亚洲欧美日韩另类精品一区二区三区 | 国产第一页久久亚洲欧美国产 | 欧美一级特黄aa大片在线观看免费 | 狼人青草久久网尹人 | 国产日韩欧美网站 | 国产成人免费全部网站 | 久草国产在线播放 | 中文字幕日韩欧美一区二区三区 | 亚洲欧美精品中文字幕 | 亚洲一区日韩一区欧美一区a | 中文字幕一区二区在线播放 | 国产成人高清精品免费观看 | 欧美啊v在线观看 | 国产精品久久久久亚洲 | 黄色理论视频 | 91热成人精品国产免费 | 99久久香蕉国产综合影院 | 午夜私人影院免费体验区 | 情侣自拍啪啪 | 欧美激情视频一区二区免费 | 一级一级 a爱片免费视频 | 一级片久久 | 欧美高清免费一级在线 | 日韩亚洲欧美一区噜噜噜 | 免费女人18毛片a级毛片视频 | 九九99精品| 一区二区三区精品国产欧美 | 成人女人a毛片在线看 | 一级特黄色毛片免费看 | 波多野结衣在线中文 |