Linux程序設(shè)計2-第二章Shell程序設(shè)計_第1頁
Linux程序設(shè)計2-第二章Shell程序設(shè)計_第2頁
Linux程序設(shè)計2-第二章Shell程序設(shè)計_第3頁
Linux程序設(shè)計2-第二章Shell程序設(shè)計_第4頁
Linux程序設(shè)計2-第二章Shell程序設(shè)計_第5頁
已閱讀5頁,還剩68頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第二章Shell程序設(shè)計基本要求1、了解什么是shell;2、掌握創(chuàng)建和執(zhí)行Shell腳本,Shell程序設(shè)計的語法。Shell腳本的概念在Linux下,Shell腳本廣泛用于系統(tǒng)管理和軟件開發(fā),是Linux系統(tǒng)管理員和開發(fā)人員必備知識之一.bash或稱BourneAgainshell:標準的GNUshell,直觀而又靈活。或是初學(xué)者的最明智選擇同時對高級和專業(yè)用戶來說也是一個強有力的工具在Linux上,bash是普通用戶的標準shell這個shell因此稱為Bourneshell的超集,一套附件和插件。意味bash和sh是兼容的:在sh中可以工作的命令,在bash中也能工作,反之則不然.用cat/etc/shells可以顯示系統(tǒng)安裝的ShellShell腳本的概念LinuxShell腳本是多個Linux命令的集合,是一個具有執(zhí)行權(quán)限的文本文件Shell腳本是一個寫入系列命令文本文件里,可以一次性執(zhí)行的可執(zhí)行文件Linux大量采用Shell腳本來完成重復(fù)性或系統(tǒng)維護工作Shell腳本類似于Windows的批處理文件(*.bat)但是功能遠強于它.可以用vi創(chuàng)建腳本,也可以用其它文本工具創(chuàng)建后上傳到Linux.在Windows下可以UltraEdit保存成Unix文本格式BashShell腳本與CShell腳本語法有差別,本章主要采用BashShell語法.Shell腳本必須有執(zhí)行權(quán)限Shell腳本格式Shell腳本必須為Linux文本文件Shell腳本的第一句必須指定解釋的Shell通常固定為#!/bin/shShell中,以井號(#)開始一個注釋行,#號及其后面跟隨的同一行的所有內(nèi)容都被忽略腳本必須有可執(zhí)行權(quán)限chmodu+xmyscript

由所有者執(zhí)行chmoda+xmyscript

同組加上可執(zhí)行權(quán)限chmod777myscript

全部用戶加上可執(zhí)行權(quán)限$,*,’,\是腳本保留字符,如果需要作為顯示字符,則需要在前面加入轉(zhuǎn)義字符\,如\\,\*,\$,\’Shell變量Shell可以使用變量,對Shell而言,所有變量值都是字符串類型Shell變量,分為三大類:系統(tǒng)變量,環(huán)境變量,用戶自定義變量所有變量不需要自定義可以直接使用系統(tǒng)變量是指BashShell內(nèi)部定義的保留變量環(huán)境變量可以看成是在整個Shell的各個程序都能訪問的全局變量用戶自定義變量由用戶自行定義.定義格式為變量名=值,等號兩邊不能有空格,引用時用$myvar=“Hello,world”#定義一個變量myvar=“hello”#錯誤定義,等號兩邊帶了空格變量的引用和顯示變量通過$來引用值A(chǔ)=“123”$A的值就是”123”,并且在運行中可以改變變量值的顯示主要通過echo命令A(yù)=100;echo$A在LinuxShell腳本里,字符串‘’和””表示不同的含義,最大區(qū)別就是在于對變量引用的處理.單引號‘’包括之中表示字符串,如果字符串包含保留字符,則保留字符失效,按原樣輸出x=5;echo‘x=$x’

輸出x=$x雙引號“”包括之中表示字符串,如果字符串包含保留字符,則保留字符生效,如變量要顯示變量值x=5;echo“x=$x”

輸出x=5變量引用實例(456)#!/bin/sh

myvar="Hello,world"

echo1=$myvar

echo2="$myvar"

echo3='$myvar'

echo4=\$myvar

echo5=\'$myvar\'

echo6="'$myvar'"

echo7='"$myvar"'

echo8=\"$myvar\"執(zhí)行腳本注意當(dāng)前路徑不在環(huán)境變量PATH當(dāng)中。換句話在當(dāng)前目錄執(zhí)行某一個程序(如a.sh),必須要加../a.sh這樣主要出于安全考慮變量名保護在shell中,由于書寫比較隨意,很容易造成變量名引寫錯情況.由于Shell不需要變量定義,所以非常容易出錯.var1書寫成$var1hello,這樣形成新的變量Shell可以用{}來保護變量的引用var1=hello;echo${var1}hello變量值的賦值(12378)shell變量不需定義即可使用,這樣對變量值初始值就有一些問題,Shell提供一些簡單的判斷或初始化機制Var=value變量賦值${variable:-value}空值置換如果變量已經(jīng)賦值,則使用該變量值。如果變量為空,則整個引用值使用value。需要注意的是,value并不賦給variable。var3=11;echo${var3:-12}類似于C語言的var3==NULL?12:var3表達echo${var3:-12}${variable:=value}空值賦值該表達式上面的區(qū)別就是,如果variable為空,則value賦給variable。echo${var4:=12};echo$var4${variable:?}空值出錯檢驗變量是否為空,如果為空的話則顯示帶有系統(tǒng)錯誤信息${variable:?"customedmessage"}檢驗變量是否為空,如果為空的話則顯示自定義錯誤信息${variable:+word}有值置換

-變量被賦值的情況下置換一個值

echo${DEBUG:+”Debugisactive.”}Shell環(huán)境變量shell環(huán)境變量是所有shell程序都會接受的參數(shù)PATH 命令搜索路徑,以冒號為分隔符.注意與DOS下不同的是,當(dāng)前目錄不在系統(tǒng)路徑里HOME 用戶home目錄的路徑名,是cd命令的默認參數(shù)IFS 定義SHELL使用的分隔符,指命令行參數(shù)分隔符IFS=$'\t\n'LOGNAME 用戶登錄名SHELL SHELL的路徑名TERM 終端類型LD_LIBRARY_PATH尋找?guī)斓穆窂?以冒號分隔定義自定義環(huán)境變量exportMY_NAME=AndrewexportPATH=/home/hxy/bin:$PATH如果每次啟動想使用自定義環(huán)境變量,需要修改home目錄下~/.bash_profile文件,可以ls–al查看取消環(huán)境變量和自定義變量用unset變量名如unsetUSERShell環(huán)境變量規(guī)定一個程序在Shell下被執(zhí)行,那么首先是在這個Shell下創(chuàng)建一個子shell.在這個子Shell再執(zhí)行程序。子Shell所有變量從上一級Shell繼承下來程序/腳本修改子Shell的環(huán)境變量。父Shell不受影響,這個主要為了安全考慮。Shell系統(tǒng)變量常用系統(tǒng)變量$n $1表示第一個參數(shù),$2表示第二個參數(shù)...$# 命令行參數(shù)的個數(shù)$0 當(dāng)前程序的名稱$? 前一個命令或函數(shù)的返回碼$* 以“參數(shù)1參數(shù)2...”

形式保存所有參數(shù)$@ 以“參數(shù)1”

“參數(shù)2”...形式保存所有參數(shù)$$ 本程序的(進程ID號)PID$! 上一個命令的PID系統(tǒng)變量的實例./sys_var.shAndrewhxy#!/bin/sh#Thisfileisusedtoexplaintheshellsystemvariable.echo"thenumberofparameteris$#";echo"thereturncodeoflastcommandis$?";echo"thescriptnameis$0";echo"theparametersare$*";xxx=10echo"\$1=$1;\$2=$2";echo"\$*=$*"echo"\$@=$@"Shell表達式運算Shell用$((expr))

來進行表達式運算echo$((1+3))它等效于let命令,即letexpr等效于$((expr))letx=1+3;echo$x$(())支持多種進制表示echo$((013))#八進制echo$((0xA4))#十六進制任意進制表示$((進制#數(shù)))echo$((2#1101010))#2進制表示echo$((8#377))#8進制表示echo$((16#D8))#16進制表示echo$((12#10))#12進制表示echo$((36#ZZYY))#36進制表示支持運算符+-*\%<><=>=<<>>expr把后面字符串當(dāng)成數(shù)學(xué)表達式計算注意每個數(shù)之間的空格expr2+4expr3\*5VAR=`expr2+4`#這里是`,即ESC下面鍵,不是’流程控制:條件語句If判斷命令語法結(jié)構(gòu)ifTEST-COMMANDS;thenCONSEQUENT-COMMANDS;[elseELSE-Commnds;]fi

注意上面在寫在一整行里的,所以在ifthenfi三個命令之間要加入;如果是多行定義;不是必要的,如下面定義ifTEST-COMMANDSthenCONSEQUENT-COMMANDSfi

TEST-COMMANDS多是一些固定檢測,包含在test或[]之中,在下一節(jié)會詳細講解[-aFILE]

如果FILE存在則為真。Test–aFILEtest-zSTRING

“STRING”

的長度為零則為真。if/then/elif/fi用來表示更復(fù)雜的結(jié)構(gòu),這跟C語言的的if()elseif()類似if/then/else/fi可以簡化成[expr]&&true_command||false_command,這樣更簡潔,但也更能看懂[-ahello.txt]&&echotrue||echofalse等同于If[-ahello.txt];thenechotrue;elseechofalse條件判斷式我們來看繁多的test測試表達式,他們出現(xiàn)if,while,case的條件判斷位置.條件表達式是有兩種等效的格式,一種是testexpr,還是有一種是[expr],test內(nèi)嵌命令會根據(jù)對表達式expr的計算結(jié)果來確定返回0(成功)或1(失敗)。可以通過顯示$?來檢查返回值在這里test,[,]都是命令!換句話說,它們必須與expr要隔著至少一個空格.象C語言一樣[expr]的書寫是錯誤的,而且從錯誤提示中很難看出這個問題來.這是C開發(fā)者要特別注意的.后面都是以[]為例來講解條件判斷表條件判斷分為幾大類文件判斷運算符,主要用于判斷文件類型或是否存在的條件字符串比較運算符,主要為比較字符串是否相同算術(shù)比較運算符,主要和于判斷兩個數(shù)之間大小關(guān)系條件判斷式(續(xù))運算符描述示例文件比較運算符-efilename如果filename存在,則為真[-e/var/log/syslog]-dfilename如果filename為目錄,則為真[-d/tmp/mydir]-ffilename如果filename為常規(guī)文件,則為真[-f/usr/bin/grep]-Lfilename如果filename為符號鏈接,則為真[-L/usr/bin/grep]-rfilename如果filename可讀,則為真[-r/var/log/syslog]-wfilename如果filename可寫,則為真[-w/var/mytmp.txt]-xfilename如果filename可執(zhí)行,則為真[-x/usr/bin/grep]filename1-ntfilename2如果filename1比filename2新,則為真[/tmp/install/etc/services-nt/etc/services]filename1-otfilename2如果filename1比filename2舊,則為真[/boot/bzImage-otarch/i386/boot/bzImage]條件判斷式(續(xù))運算符描述示例字符串比較運算符(請注意引號的使用,這是防止空格擾亂代碼的好方法)-zstring如果string長度為零,則為真[-z"$myvar"]-nstring如果string長度非零,則為真[-n"$myvar"]string=string2如果string1與string2相同,則為真["$myvar"="onetwothree"]string1!=string2如果string1與string2不同,則為真["$myvar"!="onetwothree"]算術(shù)比較運算符num1-eqnum2等于[3-eq$mynum]num1-nenum2不等于[3-ne$mynum]num1-ltnum2小于[3-lt$mynum]num1-lenum2小于或等于[3-le$mynum]num1-gtnum2大于[3-gt$mynum]Num1-genum2大于或等于[3-ge$mynum]條件判斷實例test3-gt4&&echoTrue||echofalse判斷3是否大于4if[$?-eq0];thenecho'Thatwasagoodjob!';if判斷上一個程序返回值是否為0test-d"$HOME";echo$?判斷用戶的主目錄是否存在test"abc"="def";echo$?判斷兩個字符串是否相等[-fhello.txt];echo$?判斷文件hello.txt是否存在If實例對上一個命令返回值作判斷#查找本地密碼文件是否包含當(dāng)前用戶grep$USER/etc/passwdif[$?-ne0];thenecho"notalocalaccount";fi檢測腳本執(zhí)行是否有參數(shù)if[$#-eq0];thenecho"$0noparameter">&2exit1fi字符串比較if["$(whoami)"!='root'];thenecho"Youhavenopermissiontorun$0asnon-rootuser."exit1;fi上面等效于["$(whoami)"!='root']&&(echoyouareusinganon-privilegedaccount;exit1)流程控制:多向分支Case語句類似于C語言中的switch多向分支sase語法結(jié)構(gòu)

case字符串in;模式1)command;;模式2)command;;esacC語言開發(fā)者又要注意了,模式后是)而不是:因為:也是保留字,而且執(zhí)行語句后面是;;這還是單行定義語句,多行定義如下

case字符串in

模式1)command;;模式2)command;;

…esac模式可以用多個值,用|隔開1|2|3|8|9)case實例,菜單選擇#Displayamenuecho_echo"1Restore"echo"2Backup"echo"3Unload"echo#Readandexcutetheuser'sselectionecho-n"EnterChoice:"readCHOICEcase"$CHOICE"in1)echo"Restore";;2)echo"Backup";;3)echo"Unload";;*)echo"Sorry$CHOICEisnotavalidchoice“exit1

esac*)表示類似于C語言的default分支模式可以是正則表達式,或通配符*.txt[ab].out復(fù)雜實例流程控制:bash循環(huán)機制Bash支持三種循環(huán)for

循環(huán)有兩種形式。shell腳本編程中最常見的形式是對一組值進行迭代,對每個值都執(zhí)行命令列表一次。這組值可能為空,在這種情況下命令列表就不會被執(zhí)行。另外一種形式更加類似于傳統(tǒng)的Cfor循環(huán),使用3個數(shù)學(xué)表達式來控制循環(huán)的起始條件、步進函數(shù)和結(jié)束條件。while

循環(huán)每次都在循環(huán)開始時計算一個條件的值,如果這個條件為true,就執(zhí)行命令列表。如果這個條件最初不為true,那么這些命令就永遠都不會執(zhí)行。until

循環(huán)執(zhí)行一個命令列表,并在每個循環(huán)結(jié)束時計算某個條件的值。如果這個條件為true,就再次執(zhí)行這個循環(huán)。即使條件最初不為true,這些命令也會至少被執(zhí)行一次。

流程控制:for循環(huán)for循環(huán)在shell并不是象C語言累加的形式,而是采用腳本中特有的fordo格式語法結(jié)構(gòu)forNAME[inLIST];doCOMMANDS;done這里表示從LIST依次取值(以空格為界)賦給變量Name,然后執(zhí)行dodone中的命令,這跟C語言差別非常大.如果[inLIST]

不存在的話,就使用in$@

替換且for

對每個位置參數(shù)執(zhí)行一次COMMANDS,$@是指命令行參數(shù)列表例子:

forxinabd2"mystuff";doecho$x;done如果想for實現(xiàn)象C中循環(huán)累加的結(jié)果需要用到$(())表達式for((x=2;x<5;x++));doecho$x;donefor實例#!/usr/bin/envbash#取得/etc/目錄下所有以r打頭的文件名,判斷是不是目錄

formyfilein/etc/r*doif[-d"$myfile"]thenecho"$myfile(dir)"elseecho"$myfile"fidone流程控制:while循環(huán)while

結(jié)構(gòu)允許重復(fù)執(zhí)行一系列命令,只要控制while

循環(huán)的命令執(zhí)行成功(退出狀態(tài)是零)語法格式whileCONTROL-COMMAND;doCONSEQUENT-COMMANDS;doneCONTROL-COMMAND采用if同樣的判斷test表達式這里while,do,done都是命令,在一行內(nèi)要;隔開while實例X=1while((X<=10))do echohelloXis$X letX=X+1done流程控制:util循環(huán)重復(fù)循環(huán)直到條件為真為止。until

循環(huán)和while

循環(huán)非常相似,但是正好相反,除了循環(huán)執(zhí)行直到TEST-COMMAND

執(zhí)行成功。只要這個命令測試失敗,循環(huán)就繼續(xù)。untilTEST-COMMAND;doCONSEQUENT-COMMANDS;doneutil表達式X=1until((X>10))do echohelloXis$X letX=X+1doneShift命令很多時候,變量值是一組以空格隔開的列表,如命令行參數(shù),一組文件名列表等等.在循環(huán)中可能需要逐一處理.C語言只能數(shù)組加下標,或指針變量移動來處理.那Shell腳本呢,當(dāng)然開發(fā)者可以自己處理字符串,一個一個把值分離出來,但是在Shell腳本里有更簡單辦法.使用Shift命令來處理.Shift命令每次把從命令行參數(shù)位置變量值取一個值出來,并且把總數(shù)減一.這樣處理循環(huán)起來非常簡單shift后可加整數(shù)進行一次多個移位shift3shift實例注意命令行參數(shù)總數(shù),$#每shift一次,值減一.#利用shift計算所有參數(shù)乘積,假設(shè)參數(shù)均為整數(shù)#!/bin/shresult=1while[$#-gt0]doresult=`expr$result\*$1`shiftdoneecho$result#打印所有命令行參數(shù)until[$#-eq0];doecho“para=$1count$#"

shiftdone循環(huán)跳轉(zhuǎn)機制exit,break和continue

跳出機制這些機制跟C語言是一樣的,可用于if和循環(huán)中.都是用于提前跳出break[n]中止循環(huán)過程的執(zhí)行,并且跳到下一個命令。N表示跳出嵌套的層數(shù)continue[n]停止循環(huán)過程的當(dāng)前一個反復(fù)并且跳到循環(huán)中的下一個反復(fù)過程的開始部分,n表示忽略的層數(shù)exit[n]停止shell程序的執(zhí)行,并且將返回值設(shè)置為n。break命令讓您可以從一個循環(huán)中立即退出。如果使用了嵌套循環(huán),也可以指定退出的層次數(shù)。因此如果在for循環(huán)中有一個until循環(huán),而這個for循環(huán)在另外一個for循環(huán)之中,所有這些循環(huán)又全部在一個while循環(huán)中,那么break

3就會立即結(jié)束until循環(huán)和2個for循環(huán),并將控制權(quán)返回給while循環(huán)中的代碼continue語句可以跳過命令列表中的剩下的語句,直接跳轉(zhuǎn)到下一次循環(huán)的開頭continue和break的應(yīng)用while

truedo

echo"Enterfiletoremove:c"

readFILE

iftest!-f$FILE

then

echo$FILEisnotaregularfile

continue

fi

echoremoving$FILE

rm$FILE

breakdone建立交互式腳本(1)用echo來輸出信息read接收用戶的輸入使用內(nèi)建命令read,它從標準輸入讀取變量的值,讀入單行輸入并將各個輸入詞分配給各個變量readVAR;echo$VAR使用-p選項為每次read提供提示。使用以引號括起來的字符串提供提示read-p"Insteadof$VAR,whatnumberwouldyoulike?"VAR;$echoVAR從管道里讀取ls|whilereadfile;dols$file;done

read可一次性讀取多個變量ls-i|whilereadinodefile;do\echo"File$filehasinode$inode";done交互式菜單#!/bin/bashecho"*******************************"echo"Pleaseselectyouroperation:"echo"1Copy"echo"2Delete"echo"3Backup"echo"*******************************"readopcase$opinC)echo"yourselectionisCopy";;D)echo"yourselectionisDelete";;B)echo"yourselectionisBackup";;*)echo"invalidselection"esac建立交互式腳本(2)select表達式是一種bash的擴展應(yīng)用,用戶可以從一組不同的值中進行選擇.語句結(jié)構(gòu):selectvarin...;do

breakdone$var存儲用戶所選的值select實例#!/bin/shecho"WhatisyourfavouriteOS?"selectvarin"Linux""GnuHurd""FreeBSD""Other";dobreakdoneecho"Youhaveselected$var"使用函數(shù)腳本的函數(shù)比較受限制不能單獨寫在一個腳本里,至少有一個調(diào)用語句定義function_name(){...}函數(shù)用return返回值函數(shù)參數(shù)也采用$1,$2之類進行傳輸show(){echo"show$*"}echo$*echo"afterfunction"showcdecho$*函數(shù)實例#!/usr/bin/envbash

myvar="helloheh"

myfunc(){localxlocalmyvar="onetwothree"forxin$myvardoecho$xdone}

myfunc

echo$myvar$x簡單腳本調(diào)試簡單一般用echo直接輸出內(nèi)部變量,復(fù)雜一點采用trap命令也在腳本執(zhí)行時加入-x參數(shù)sh–xmenu1.sh#sh是Shell程序名字,表示運行menu1.sh并顯示內(nèi)部變量值或bash–xmenu1.sh也可執(zhí)行該腳本并顯示所有變量的值。不執(zhí)行,只執(zhí)行語法檢查-n參數(shù)sh–nmenu1.sh不報錯表示沒有錯誤用trap調(diào)試腳本trap命令用于捕獲指定的信號并執(zhí)行預(yù)定義的命令。其基本的語法是:

trap‘command’

signal其中signal是要捕獲的信號,command是捕獲到指定的信號之后,所要執(zhí)行的命令??梢杂胟ill–l命令看到系統(tǒng)中全部可用的信號名,捕獲信號后所執(zhí)行的命令可以是任何一條或多條合法的shell語句,也可以是一個函數(shù)名。shell腳本在執(zhí)行時,會產(chǎn)生三個所謂的“偽信號”,(之所以稱之為“偽信號”是因為這三個信號是由shell產(chǎn)生的,而其它的信號是由操作系統(tǒng)產(chǎn)生的),通過使用trap命令捕獲這三個“偽信號”并輸出相關(guān)信息對調(diào)試非常有幫助。Shell偽信號

EXIT從一個函數(shù)中退出或整個腳本執(zhí)行完畢

ERR當(dāng)一條命令返回非零狀態(tài)時(代表命令執(zhí)行不成功

DEBUG腳本中每一條命令執(zhí)行之前trap調(diào)試腳本通過捕獲EXIT信號,我們可以在shell腳本中止執(zhí)行或從函數(shù)中退出時,輸出某些想要跟蹤的變量的值,并由此來判斷腳本的執(zhí)行狀態(tài)以及出錯原因,其使用方法是:trap'command'EXIT或trap'command'0通過捕獲ERR信號,我們可以方便的追蹤執(zhí)行不成功的命令或函數(shù),并輸出相關(guān)的調(diào)試信息,以下是一個捕獲ERR信號的示例程序,其中的$LINENO是一個shell的內(nèi)置變量,代表shell腳本的當(dāng)前行號。trap'ERRTRAP$LINENO'ERRtrap調(diào)試腳本在調(diào)試過程中,為了跟蹤某些變量的值,我們常常需要在shell腳本的許多地方插入相同的echo語句來打印相關(guān)變量的值,這種做法顯得煩瑣而笨拙。而通過捕獲DEBUG信號,我們只需要一條trap語句就可以完成對相關(guān)變量的全程跟蹤。trap'echo“beforeexecuteline:$LINENO,a=$a,b=$b,c=$c”'DEBUG

trapERR實例ERRTRAP(){echo"[LINE:$1]Error:Commandorfunctionexitedwithstatus$?“}foo(){return1;}trap'ERRTRAP$LINENO'ERRabcfooTrapEXITERRTRAP(){echo"[LINE:$1]Error:Commandorfunctionexitedwithstatus$?“}foo(){return1;}trap'ERRTRAP$LINENO'EXITabcfooTrapDebug#!/bin/bashtrap'echo"beforeexecuteline:$LINENO,a=$a,b=$b,c=$c"'DEBUGa=1if["$a"-eq1]Thenb=2Elseb=1Fic=3echo"End"例:Service腳本/sbin/service用于控制各種服務(wù)的啟動和停止#!/bin/sh#Setupadefaultsearchpath.PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin"exportPATHVERSION="`basename$0`ver.0.91"USAGE="Usage:`basename$0`<option>|--status-all|\[service_name[command|--full-restart]]"SERVICE=SERVICEDIR="/etc/init.d"OPTIONS=if[$#-eq0];then#判斷參數(shù)是否0,腳本要求必須有參數(shù)

echo$"${USAGE}">&2exit1fi

復(fù)雜腳本樣例1.檢測某個進程是否正常工作check_process.sh2.檢測磁盤空間是否足夠,并報警check_disk.sh列出目錄樹#!/bin/sh

#dtree:Usage:dtree[anydirectory]

dir=${1:-.}

find$dir-typed-print|sort-f|sed-e"s,^$1,,"-e"/^$/d"-e"s,[^/]*/([^/]*)$,’----1’,"-e"s,[^/]*/,|,g"

init腳本例子一個init腳本啟動在UNIX和Linux機器上的系統(tǒng)服務(wù)存儲在系統(tǒng)的特定位置,比如/etc/rc,/etc/rc.d/init.d或者/etc/init.d目錄下awk2、awk模式模式可匹配特定行,可以是以下任意一個:/正則表達式/:如awk'/[0-9]+\.[0-9]*/{print}'file關(guān)系表達式:如awk'$1=="fred"{print$3}'file模式匹配表達式:如awk'$5~/root/{print}'file3、awk操作操作位于{}內(nèi),由換行符或分號隔開,對匹配的行進行操作,包括:變量或數(shù)組賦值輸出命令:如printprintf內(nèi)置函數(shù):如splitindexmatchsubstr等控制流命令:如ifforwhile等1、awk腳本組成awk腳本是由模式和操作組成的:awk‘BEGIN{print“start”}pattern{commands}END{print“end”}’fileawk4、awk內(nèi)置變量ARGC:命令行參數(shù)個數(shù)ARGV:命令行參數(shù)數(shù)組ARGIND:當(dāng)前文件索引(從1開始)FILENAME:當(dāng)前輸入文件名FS:輸入字段分隔符(默認空格)NR:當(dāng)前記錄數(shù)NF:當(dāng)前記錄字段數(shù)OFS:輸出字段分隔符(默認空格)ORS:輸出記錄分隔符(新行)RS:輸入記錄分隔符(新行)RSTART:被匹配函數(shù)匹配的字符串首RLENGTH:被匹配函數(shù)匹配的字符串長度OFMT:數(shù)字的輸出格式(%.6g)IGNORECASE:控制大小寫敏感(0:敏感)awk-F'%''BEGIN{

OFMT="%.3g";

#輸出數(shù)字保留3位

IGNORECASE=1;

#忽略大小寫

OFS="&";

#輸出字段分隔符}{

if(match($1,/^A.*f$/)>0){

#匹配函數(shù)

printNR,NF,RSTART,RLENGTH,$2+0;}}'file#輸出1&3&1&2&2.233&4&1&4&1.32#假設(shè)file內(nèi)容如下af%2.23423%ssxxx%1.2asdf%1.323242%xx%ssawk函數(shù)名含義sub(e,r,src)將src中匹配e的第一個字串替換為rgsub(e,r,src)將src中匹配e的全部字串替換為rindex(s1,s2)返回s2在s1的索引(未找到返回0)length(s)返回s的長度substr(s,i,len)返回s中從i位置起,長度為len的字串match(s,e)返回e在s中匹配的字串的起始位置split(s,arr,sep)將s按sep分割,元素存于數(shù)組arr中tolower(s)將s轉(zhuǎn)換為小寫toupper將s轉(zhuǎn)換為大寫strftime將時間戳轉(zhuǎn)換為時間字符串注:awk函數(shù)返回的下標從1開始,數(shù)組下標也從1開始假設(shè)awk變量s="thisisatest2010test!"awk'BEGIN{gsub(/[0-9]+/,"!",s);prints;}'#thisisatest!test!"awk'BEGIN{printindex(info,"test");}'#11awk'BEGIN{printmatch(s,/[0-9]+/);}'#15awk'BEGIN{printsubstr(s,4,10);}'#sisatesawk'BEGIN{split(info,a,"");for(kina){printf("%s%s,",k,a[k]);}printf("\n");}'#4test,1this,2is,3a,echo`date+%s`|awk'{printstrftime("%Y-%m-%d%H:%M:%S",$0)}'#2015-04-0216:24:525、awk內(nèi)置函數(shù)awkawk-F"|"'BEGIN{#點擊應(yīng)用推薦行為ID

CLICK_APP_REC_ACTION_ID=321

click_user_num=0; }{for(i=1;i<=NF;i++){ split($i,arr,":");if(arr[1]==CLICK_APP_REC_ACTION_ID){click_user_num=arr[3];break; }}}END{printclick_user_num;}'${file}6、一個實例需求:統(tǒng)計點擊應(yīng)用推薦的用戶數(shù)文件file格式為:110:138:86|111:7:5|321:6:6|9:72:62|113:27:23|...格式含義如下:

行為ID:點擊次數(shù):點擊用戶數(shù)sedsed選項-n:關(guān)閉默認輸出-r:支持擴展正則+?(){}|-i:修改原文件,慎用!sed定址$:表示文件最后一行0個:沒有定址,所有行1個:行號,處理行號所在位置的行2個:行號、正則表達式,處理被行號或正則表達式包起來的行sed命令p:打印行d:刪除行s:替換w:另存為a:當(dāng)前行后添加一行i:在當(dāng)前行上面插入文本1、sed簡介sed用來對文本進行過濾與替換,一次僅讀取一行內(nèi)容。2、sed工作原理sed把當(dāng)前行存儲在臨時緩沖區(qū)中(稱為“模式空間”),用sed命令處理緩沖區(qū)中的內(nèi)容,處理完成后,把緩沖區(qū)的內(nèi)容送往屏幕。3、sed語法sed[選項][定址commands][inputfile]sed刪除命令:d命令$sed'2d'file

#刪除file文件的第二行$sed'2,$d'file

#刪除file文件的第二行到末尾所有行$sed'$d'file

#刪除file文件的最后一行$sed'/test/d'file

#刪除file文件所有包含test的行選定行的范圍:逗號$sed-n'/test/,/check/p'file #打印所有在模板test和check所確定的范圍內(nèi)的行$sed-n'5,/^test/p'file #打印從第五行到第一個包含以test開始的行之間的所有行$sed'/test/,/love/s/$/xxx/'file

#對于模板test和love之間的行,每行的末尾用xxx替換替換:s命令$sed's/test/xxx/g'file

#把行中所有的test替換為xxx;若無g,則只替換第一個$sed-n-r's/(love)ab/1rs/'file #love被標記為1,所有l(wèi)oveab會被替換成lovers$sed's#10#100#g'file #“#”緊跟s后,是分隔符,代替了默認的“/”分隔符追加命令:a命令$sed'/^test/axxxx'file

#在以test開頭的行后插入新行xxxx插入命令:i命令$sed'/^test/ixxxx'file

#在以test開頭的行前插入新行xxxx4、sed實例cutcut選項-b:以字節(jié)為單位顯示選中內(nèi)容-c:以字符為單位顯示選中內(nèi)容-f:以字段為單位顯示選中內(nèi)容-d:指定字段的分界符,默認為制表符cut范圍n:第n個字段n-:從第n個到最后一個字段n-m:從第n到第m個字段,包括m-m:從第1到第m個字段,包括m-:從行開頭到行的最后n,m:第n個和第m個字段常用實例#截取指定字段$echoroot:x:0:0:root:/root:/bin/bash|cut-d:-f1,5$echoroot:x:0:0:root:/root:/bin/bash|cut-d:-f1-$echoroot:x:0:0:root:/root:/bin/bash|cut-d:-f2-4#截取指定個數(shù)的字符$echoroot:x:0:0:root:/root:/bin/bash|cut-c2-5$echoroot:x:0:0:root:/root:/bin/bash|cut-c-2$echoroot:x:0:0:root:/root:/bin/bash|cut-c2-1、cut簡介從文件的每一行剪切字節(jié)、字符和字段并將它們寫至標準輸出。2、cut語法cut[選項][范圍]文件tr用一個字符來替換另外一個字符刪除字符串中的指定子串合并字符串中重復(fù)串tr[option]set1set2<input-filetr選項默認:用str2替換str1-d:刪除str1中所有輸入字符-s:刪除重復(fù)字符序列,只保留第一個常用實例#小寫轉(zhuǎn)大寫$tr'r''R'<./pass.txt$tr'[a-z]''[A-Z]'<./pass.txt#刪除字符$tr-d[0-9]<filename#刪除所有數(shù)字$tr-d''<filename #刪除所有空格#合并重復(fù)字符$echoaaaabbbbccccddddddd|tr-s"[a-z]"#abcd#字符串的替換$echo123456789|tr'1-9''[A*5]'BCDE#AAAAABCDE$echo123456789|tr'1-9''[A*6]'BCDE#AAAAAABCDtr字符串范圍列表[a-z]:a-z內(nèi)的字符組成的字符串[A-Z]:A-Z內(nèi)的字符組成的字符串[0-9]:數(shù)字串\octal:一個三位的八進制數(shù)[O*n]:表示字符O重復(fù)出現(xiàn)指定次數(shù)n1、tr簡介2、tr語法grepgrep[options]patternfiles-c:只顯示有多少行匹配,而不具體顯示匹配的行-h:不顯示文件名-H:在每個符合的行前加上符合的文件名稱-i:在字符串比較的時候忽略大小寫-l:只顯示包含匹配模板的行的文件名清單-L:只顯示不包含匹配模板的行的文件名清單-n:在每一行前面打印該行在文件中的行數(shù)-v:反向檢索,只顯示不匹配的行-w:只顯示完整單詞的匹配-x:只顯示完整行的匹配-q:不顯示任何輸出-C:列出符合行外并列出上下各NUM行,默認為2-B:列出符合行外并列出之前的NUM行-A:列出符合行外并列出之后的NUM行-E:擴展正則表達式-r/-R:若是目錄,則遞歸搜索其所有子目錄和文件1、grep語法2、grep參數(shù)3、grep退出狀態(tài)0:成功1:無法找到匹配的pattern2:文件不存在$grep'root'/etc/passwdroot:x:0:0:root:/root:/bin/bash$echo$?0#用戶root1并不存在$grep'root1'/etc/passwd$echo$?1#/etc/passwd1文件并不存在$grep'root'/etc/passwd1grep:/etc/passwd1:Nosuchfileordirectory$echo$?2grep$grepNWfile

#打印出file中所有包含NW的行$grep'^n'file

#打印出以n開頭的行$grep'4$'file

#打印出以4結(jié)尾的行$grep'5\..'file

#打印出第一個字符是5,后面跟著一個.字符,再后面是任意字符的行$grep'\.5'file

#打印出所有包含.5的行$grep'^[we]'file

#打印出所有以w或e開頭的行$grep'[^0-9]'file

#打印出所有不是以0-9開頭的行$grep'[A-Z][A-Z]'file

#打印出所有前一個字符是大寫,后跟一個空格及一個大寫字母的行$grep'[a-z]\{9\}'file

#打印所有包含至少有9個連續(xù)小寫字符的字符串的行$grep'\<north'file

#打印所有以north開頭的單詞的行$grep'\<north\>'file

#打印所有包含單詞north的行$grep'^n\w*'file

#第一個字符是n,后面是任意字母或者數(shù)字$egrep'NW|EA'file

#打印所有包含NW或EA的行?;騡rep-E$grep'NW\|EA'file

#對于標準grep,若在擴展元字符前面加\,grep會自動啟用-E4、greppattern實例dd用指定大小的塊拷貝一個文件,并在拷貝的同時進行指定的轉(zhuǎn)換1、dd描述2、dd格式dd-if=-of=...3、dd常用參數(shù)if=輸入文件名:缺省為標準輸入of=輸出文件名:缺省為標準輸出ibs=bytes:一次讀入bytes個字節(jié),即指定一個塊大小為bytes個字節(jié)obs=bytes:一次輸出bytes個字節(jié),即指定一個塊大小為bytes個字節(jié)bs=bytes:同時設(shè)置讀入/輸出的塊大小為bytes個字節(jié)skip=blocks:從輸入文件開頭跳過blocks個塊后再開始復(fù)制count=blocks:僅拷貝blocks個塊,塊大小等于ibs指定的字節(jié)數(shù)conv=conversion:用指定的參數(shù)轉(zhuǎn)換文件(lcase:大寫轉(zhuǎn)小寫;ucase:小寫轉(zhuǎn)大寫)4、dd備份與恢復(fù)備份并壓縮:ddif=/dev/hdb|gzip>/root/image.gz恢復(fù)壓縮文件:gzip-dc/root/image.gz|ddof=/dev/hdb${}用法取值含義結(jié)果${file#*/}拿掉第一條/及其左邊的字串dir1/dir2/dir3/my.file.txt${file##*/}拿掉最后一條/及其左邊的字串my.file.txt${file#*.}拿掉第一個.及其左邊的字串file.txt${file##*.}拿掉最后一個.及其左邊的字串txt${file%/*}拿掉最后條/及其右邊的字串/dir1/dir2/dir3${file%%/*}拿掉第一條/及其右邊的字串(空值)${file%.*}拿掉最后一個.及其右邊的字串/dir1/dir2/dir3/my.file${file%%.*}拿掉第一個.及其右邊的字串/dir1/dir2/dir3/my${file:0:5}提取最左邊的5個字符/dir1${file:5:5}提取第5個字符右邊的連續(xù)5個字符/dir2假設(shè):file=/dir1/dir2/dir3/my.file.txt1、字符串取值${}用法字符串替換含義結(jié)果${file/dir/path}將第一個dir提換為path/path1/dir2/dir3/my.file.txt${file//dir/path}將全部dir提換為path/path1/path2/path3/my.file.txt${#file}計算出變量值的長度27賦值含義var=${str-expr}當(dāng)str未定義時,var=expr;否則var=$strvar=${str:-expr}當(dāng)str未定義或為空值時,var=expr;否則var=$strvar=${str+expr}與-正好相反:當(dāng)str未定義時,var=$str;否則var=exprvar=${str:+expr}與:-正好相反:當(dāng)str未定義或為空值時,var=$str;否則var=exprvar=${str=expr}當(dāng)str未定義時,var=expr,str=expr;否則str不變,var=$strvar=${str:=expr}當(dāng)str未定義或為空值時,var=expr,str=expr;否則str不變,var=$strvar=${str?expr}當(dāng)str未定義時,expr輸出至stderr;否則var=$strvar=${str:?expr}當(dāng)str未定義或為空值時,expr輸出至stderr;否則var=$str假設(shè):file=/dir1/dir2/dir3/my.file.txt2、字符串替換3、字符串賦值(())用法a=$((5+3))#加法a=$((5-3))#減法a=$((5*3))#乘法a=$((5/3))#除法a=$((5**3))#冪運算a=$((5%3))#

取模2、使用C風(fēng)格的變量處理((a=23)) #給一個變量賦值((a++)) #變量'a'后加1((a--)) #變量'a'后減1((++a)) #變量'a'預(yù)加1((--a)) #變量'a'預(yù)減1n=1;((--a))&&echo"True"||echo"False"#Falsen=1;((a--))&&echo"True"||echo"False"#True1、算術(shù)擴展和賦值求交集、并集、差集1、求文件交集awk'ARGIND==1{g[$1]=1}ARGIND>1&&(g[$1]==ARGIND-1){g[$1]++}END{for(iing){if(g[i]==ARGIND){printi;}}}'f1f2f3...fn2、求文件并集awk'{a[$1]}END{printlength(a)}'f1f2f33、求文件差集awk'ARGIND==1{g[$1]}ARGIND>1&&!($1ing){b[$1]}END{for(iinb){

printi;}

溫馨提示

  • 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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論