Linux 應(yīng)用基礎(chǔ)教程-Shell腳本編程1_第1頁
Linux 應(yīng)用基礎(chǔ)教程-Shell腳本編程1_第2頁
Linux 應(yīng)用基礎(chǔ)教程-Shell腳本編程1_第3頁
Linux 應(yīng)用基礎(chǔ)教程-Shell腳本編程1_第4頁
Linux 應(yīng)用基礎(chǔ)教程-Shell腳本編程1_第5頁
已閱讀5頁,還剩169頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第10章

bash腳本編程本章內(nèi)容要點(diǎn)Shell腳本的編制、執(zhí)行和調(diào)試Shell腳本的成分和編碼規(guī)范Shell變量替換擴(kuò)展、數(shù)值計算、輸入輸出變量分類,位置參數(shù)變量和特殊參數(shù)變量條件測試(文件測試、字符串測試、整數(shù)測試)分支流程控制(if、case)循環(huán)流程控制(for、while、until、select)函數(shù)的定義和調(diào)用、返回值使用循環(huán)分析命令行參數(shù)2023年2月4日2本章學(xué)習(xí)目標(biāo)熟悉Shell腳本的編碼規(guī)范,掌握執(zhí)行和調(diào)試方法掌握對變量進(jìn)行整數(shù)運(yùn)算和間接引用的方法理解位置參數(shù)變量和特殊參數(shù)變量的用途掌握條件測試的使用[]、[[]]、(())掌握各種流程控制語句的使用if、casefor、while、until、select、break、continue掌握函數(shù)的定義、調(diào)用和傳遞返回值的方法掌握命令行參數(shù)、位置參數(shù)的操作(shift、getopts)2023年2月4日3Shell編程基礎(chǔ)2023年2月4日4Shell腳本和Shell編程當(dāng)命令不在命令行中執(zhí)行,而是從一個文件中執(zhí)行時,該文件就稱為Shell腳本。Shell腳本是純文本文件。Shell腳本通常以.sh作為后綴名,但不是必須。Shell腳本是以行為單位的,在執(zhí)行腳本的時候會分解成一行一行依次執(zhí)行。Shell是一種功能強(qiáng)大的解釋型編程語言通常用于完成特定的、較復(fù)雜的系統(tǒng)管理任務(wù)Shell腳本語言非常擅長處理文本類型的數(shù)據(jù)2023年2月4日5Shell腳本的成分程序元素保留字、運(yùn)算符、表達(dá)式變量、數(shù)組、輸入輸出控制結(jié)構(gòu)(順序、分支、循環(huán)、子程序調(diào)用)Shell功能

【參見第2、3章內(nèi)容】執(zhí)行命令(內(nèi)置命令、外部命令、自編程序)重定向、管道、命令替換、命令聚合通配符、注釋符、……Shell環(huán)境2023年2月4日6Shell腳本的建立與執(zhí)行Shell腳本的建立使用文本編輯器編輯腳本文件$viscript-file為腳本文件添加可執(zhí)行權(quán)限$chmod+xscript-fileShell腳本的執(zhí)行在子Shell中執(zhí)行$bashscript-file$script-file在當(dāng)前Shell中執(zhí)行$sourcescript-file$.script-file2023年2月4日7PATH環(huán)境變量的默認(rèn)值不包含當(dāng)前目錄,若腳本文件在當(dāng)前目錄,應(yīng)使用./script-filePATH環(huán)境變量的默認(rèn)值包含~/bin目錄,用戶可以將自己的腳本文件存放在~/bin目錄,之后即可直接調(diào)用腳本文件名執(zhí)行腳本了Shell腳本的編碼規(guī)范以#!開頭:通知系統(tǒng)用何解釋器執(zhí)行此腳本#!/bin/bash#!/bin/ksh以注釋形式說明如下的內(nèi)容:#腳本名稱#腳本功能#作者及聯(lián)系方式#版本更新記錄#版權(quán)聲明#對算法做簡要說明(如果是復(fù)雜腳本)2023年2月4日8Shell腳本舉例(1)2023年2月4日9#!/bin/bash#ThisisthefirstBashshellprogram#Scriptname:greetings.shechoecho

-e"Hello$LOGNAME,\c"echo"it'snicetalkingtoyou."echo

-n"Yourpresentworkingdirectoryis:"pwd#Showthenameofpresentdirectoryechoecho

-e"Thetimeis`date+%T`!.\nBye"echoShell腳本舉例(2)2023年2月4日10#!/bin/bash##ScriptName:/etc/cron.daily/ntpdate#使用NTP的客戶端命令ntpdate與遠(yuǎn)程N(yùn)TP服務(wù)器進(jìn)行同步#也可以用局域網(wǎng)內(nèi)的NTP服務(wù)器替換/usr/sbin/ntpdate-s#更改硬件時鐘時都會記錄在/etc/adjtime文件中#使hwclock根據(jù)先前的記錄來估算硬件時鐘的偏差,#并用來校正目前的硬件時鐘/sbin/hwclock--adjust#將系統(tǒng)時鐘同步到硬件時鐘/sbin/hwclock–systohc腳本調(diào)試方法在bash調(diào)用腳本時使用參數(shù)$bash[-x][-n][-v]scriptName在腳本中使用bash內(nèi)置的

set命令使整個或部分腳本處于調(diào)試模式開啟:set[-x][-n][-v]結(jié)束:set[+x][+n][+v]2023年2月4日11腳本調(diào)試12023年2月4日12sh

–x

腳本名該選項(xiàng)可以使用戶跟蹤腳本的執(zhí)行,此時shell

對腳本中每條命令的處理過程為:先執(zhí)行替換,然后顯示,再執(zhí)行它。shell

顯示腳本中的行時,會在行首添加一個加號“+”。sh–v

腳本名在執(zhí)行腳本之前,按輸入的原樣打印腳本中的各行。sh–n

腳本名對腳本進(jìn)行語法檢查,但不執(zhí)行腳本。如果存在語法錯誤,shell

會報錯,如果沒有錯誤,則不顯示任何內(nèi)容。腳本調(diào)試舉例1對腳本進(jìn)行語法檢查$bash-ngreetings.sh顯示腳本中每個原始命令行及其執(zhí)行結(jié)果$bash-vgreetings.sh以調(diào)試模式執(zhí)行腳本$bash-xgreetings.sh2023年2月4日13腳本調(diào)試2——set命令在腳本內(nèi)使用set命令開啟調(diào)試選項(xiàng)set-x:顯示由shell執(zhí)行的命令及其參數(shù)set-v:顯示由shell讀入的命令行set-n

:讀取命令但不執(zhí)行他們,用于語法檢查在腳本內(nèi)使用set命令關(guān)閉已開啟的調(diào)試選項(xiàng)set+xset+vset+n2023年2月4日14腳本調(diào)試舉例2$bashgreetings.sh./greetings.sh$sourcegreetings.sh2023年2月4日15#!/bin/bash#ThisisthefirstBashshellprogram#Scriptname:greetings.shset-x###TurnONdebugmode###echoecho-e"Hello$LOGNAME,\c"echo"it'snicetalkingtoyou."echo-n"Yourpresentworkingdirectoryis:"pwd#Showthenameofpresentdirectoryechoset+x###TurnOFFdebugmode###echo-e"Thetimeis`date+%T`!.\nBye"echoShell腳本的類型非交互式腳本不需要讀取用戶的輸入,也不用向用戶反饋某些信息每次執(zhí)行都是可預(yù)見的,因?yàn)樗蛔x取用戶輸入,參數(shù)是固定的可以在后臺執(zhí)行交互式腳本腳本可以讀取用戶的輸入,實(shí)時向用戶反饋信息(輸出某些信息)這樣的腳本更靈活,每次執(zhí)行時的參數(shù)可由用戶動態(tài)設(shè)定用戶界面更友好,但不適用于自動化任務(wù)(如cron任務(wù))2023年2月4日16學(xué)習(xí)Shell編程的前提掌握一種文本編輯器的使用(Vi)熟悉Linux文件系統(tǒng)的布局學(xué)習(xí)Shell的各種功能重定向、管道、命令替換、命令聚合學(xué)習(xí)各種管理和監(jiān)視命令的使用用戶管理、權(quán)限管理、進(jìn)程管理、包管理……系統(tǒng)監(jiān)視、網(wǎng)絡(luò)監(jiān)視……學(xué)習(xí)各種文本文件工具的使用cat、grep、tr、sed、awk……正則表達(dá)式2023年2月4日17系統(tǒng)的配置文件幾乎都是純文本文件變量和表達(dá)式2023年2月4日18Shell變量操作變量替換擴(kuò)展變量測試變量的字符串操作變量的間接引用變量的數(shù)值計算$[expression]$((expression))exprletdeclare-i2023年2月4日19輸入變量賦值name=valuereadonly從標(biāo)準(zhǔn)輸入讀取read輸出echoprintf變量替換擴(kuò)展——變量測試2023年2月4日20UseDefaultValues${var:-word}若var存在且非空,則值為$var;若var未定義或?yàn)榭罩?則值為word,但var的值不變。AssignDefaultValues${var:=word}若var存在且非空,則值為$var;若var未定義或?yàn)榭罩?則值為word,且var被賦值word。DisplayErrorifNullorUnset${var:?word}若var存在且非空,則值為$var;若var未定義或?yàn)榭罩?則輸出信息word,并終止腳本。UseAlternateValue${var:+word}若var存在且非空,則值為word;否則返回空值,但var的值不變。變量測試舉例2023年2月4日21color=bluenewcolor=${color:-grey}unsetcolorecho"Theskyis${color:-grey}today"echo

$colorecho"Theskyis${color:=grey}today"echo

$colorecho"Theskyis${color:?error}today"echo

$colorecho"Theskyis${color:+blue}today"echo

$color變量替換擴(kuò)展

——字符串計數(shù)、截取2023年2月4日22${#var}返回字符串變量var

的長度${var:m}返回${var}中從第m個字符到最后的部分${var:m:len}返回${var}中從第m個字符開始,長度為len的部分${var#pattern}刪除${var}中開頭部分與pattern匹配的最小部分${var##pattern}刪除${var}中開頭部分與pattern匹配的最大部分${var%pattern}刪除${var}中結(jié)尾部分與pattern匹配的最小部分${var%%pattern}刪除${var}中結(jié)尾部分與pattern匹配的最大部分m的取值從0到${#var}-1注:pattern中可以使用通配符。字符串變量替換擴(kuò)展舉例12023年2月4日23str='Ilovelinux.IloveUNIXtoo.’echo${#str}30echo${#str:13}IloveUNIXtoo.echo

${#str:7:5}linuxecho

${str#Ilove}linux.IloveUNIXtoo.echo

${str#I*.}IloveUNIXtoo.echo

${str##I*}

變量替換擴(kuò)展

——字符串替換2023年2月4日24${var/old/new}用new替換${var}中第一次出現(xiàn)的old${var//old/new}用new替換${var}中所有的old(全局替換)${var/#old/new}用new替換${var}中開頭部分與old匹配的部分${var/%old/new}用new替換${var}中結(jié)尾部分與old匹配的部分注:(1)old

中可以使用通配符。(2)var可以是@

或*,表示對每個位置參數(shù)進(jìn)行替換字符串變量替換擴(kuò)展舉例22023年2月4日25str='Ilovelinux.IloveUNIXtoo.’echo${str/love/like}Ilikelinux.IloveUNIXtoo.echo${str//love/like}Ilikelinux.IlikeUNIXtoo.echo

${str/I*linux/IlikeFreeBSD}IlikeFreeBSD.IloveUNIXtoo.echo${str/#Ilove/"J'aime"}J'aimelinux.IloveUNIXtoo.echo${str//Ilove/"J'aime"}J'aimelinux.J'aimeUNIXtoo.echo

${str/%too./also.}Ilovelinux.IloveUNIXalso.字符串變量替換擴(kuò)展舉例32023年2月4日26set1v11v21v31v4echo

$@1v11v21v31v4echo

${@/1/a}av1av2av3av4echo

${@//1/a}avaav2av3av4echo${@/%1/a}1va1v21v31v4變量的間接引用通過str2

的值來引用str1

的值2023年2月4日27str1="HelloWorld"str2=str1echo

$str2#bash2.0以上才支持newstr=${!str2}echo$newstrHelloWorld或echo${!str2}HelloWorld

evalnewstr=\$$str2echo$newstrHelloWorld或evalecho\$$str2HelloWorld

?變量的間接引用(續(xù))2023年2月4日28通過x

的值來引用CENTOS_URL

的值x="CENTOS"CENTOS_URL="/centos/"#bash2.0以上才支持newstr=${x}_URLecho$newstrCENTOS_URLecho${!newstr}/centos/evalnewstr=\$${x}_URLecho$newstr或evalecho\$${x}_URLShell內(nèi)置命令——eval2023年2月4日29listpage="ls-l|more"eval

$listpageeval$(ssh-agent)evalnewstr=\$$str2evalecho\$${x}_URL

evalarg1[arg2]...[argN]對參數(shù)進(jìn)行兩次掃描和替換將所有的參數(shù)連接成一個表達(dá)式,并計算或執(zhí)行該表達(dá)式參數(shù)中的任何變量都將被展開Shell變量的分類用戶自定義變量由用戶自己定義、修改和使用Shell環(huán)境變量由系統(tǒng)維護(hù),用于設(shè)置用戶的Shell工作環(huán)境只有少數(shù)的變量用戶可以修改其值位置參數(shù)變量(PositionalParameters)通過命令行給程序傳遞執(zhí)行參數(shù)可用shift命令實(shí)現(xiàn)位置參數(shù)的遷移專用參數(shù)變量(SpecialParameters)Bash預(yù)定義的特殊變量用戶不能修改其值2023年2月4日30位置參數(shù)變量是一組特殊的內(nèi)置變量跟在腳本名后面的用空格隔開的每個字符串$1表示第1個參數(shù)值,……,$9表示第9個參數(shù)值${10}表示第10個參數(shù)值,${11}表示第11個參數(shù)值,……位置參數(shù)的用途從shell命令/腳本的命令行接受參數(shù)在調(diào)用shell函數(shù)時為其傳遞參數(shù)2023年2月4日31專用參數(shù)變量命令行參數(shù)相關(guān)$*將所有位置參量看成一個字符串(以空格間隔)。$@將每個位置參量看成單獨(dú)的字符串(以空格間隔)?!?*”將所有位置參量看成一個字符串(以$IFS間隔)?!?@”將每個位置參量看成單獨(dú)的字符串(以空格間隔)。$0命令行上輸入的Shell程序名。$#

表示命令行上參數(shù)的個數(shù)。進(jìn)程狀態(tài)相關(guān)$?

表示上一條命令執(zhí)行后的返回值$$

當(dāng)前進(jìn)程的進(jìn)程號$!

顯示運(yùn)行在后臺的最后一個作業(yè)的PID$_

在此之前執(zhí)行的命令或腳本的最后一個參數(shù)2023年2月4日32位置參數(shù)和專用參數(shù)舉例執(zhí)行腳本$./vartest.sh1‘23’45abcdefg2023年2月4日33#!/bin/bash#ScriptName:vartest.sh#TotestPositionalParameters&SpecialParameters.echo"Hello,$USER,theoutputofthisscriptareasfollows:"echo"Thescriptnameis:$(basename$0)"echo"Thefirstparamofthescriptis:$1"echo"Thesecondparamofthescriptis:$2"echo"Thetenthparamofthescriptis:${10}"echo"Alltheparamsyouinputare:$@"echo"Alltheparamsyouinputare:$*"echo"Thenumberoftheparamsyouinputare:$#"echo"TheprocessIDforthisscriptis:$$"echo"Theexitstatusofthisscriptis:$?”$@、$*和環(huán)境變量IFS2023年2月4日梁如軍(linuxbooks@126.com)CreativeCommonsLicense(BY-NC-SA)34#!/bin/bash#ScriptName:ifsargs.sh####SettheIFSto|####IFS='|'echo"Command-LineArgumentsDemo“echo"*Allargsdisplayedusing\$@positionalparameter*"echo$@echo"*Allargsdisplayedusing\$*positionalparameter*"echo$*echo'*Allargsdisplayedusing"$@"positionalparameter*'echo"$@"#***doublequoteadded***#echo'*Allargsdisplayedusing"$*"positionalparameter*'echo"$*"#***doublequoteadded***#位置參數(shù)和shift命令將位置參量列表依次左移n次,缺省為左移一次一旦位置參量列表被移動,最左端的那個參數(shù)就會從列表中刪除經(jīng)常與循環(huán)結(jié)構(gòu)語句一起使用,以便遍歷每一個位置參數(shù)2023年2月4日35shift

[n]#!/bin/sh#ScriptName:pp_shift.sh#TotestPositionalParameters&Shift.echo"Thescriptnameis:$0"echo'$1'=$1,'$2'=$2,'$3'=$3,'$4'=$4--'$#'="$#"echo'$@':"$@"shift#向左移動所有的位置參數(shù)1次echo'$1'=$1,'$2'=$2,'$3'=$3,'$4'=$4--'$#'="$#"echo'$@':"$@"shift2#向左移動所有的位置參數(shù)2次echo'$1'=$1,'$2'=$2,'$3'=$3,'$4'=$4--'$#'="$#"echo'$@':"$@"$./pp_shift.sh1b3d4f退出/返回狀態(tài)$?:返回上一條語句或腳本執(zhí)行的狀態(tài)0:成功1-255:不成功exit

命令exit

命令用于退出腳本或當(dāng)前Shell

n

是一個從0到255的整數(shù)0表示成功退出,非零表示遇到某種失敗返回值被保存在狀態(tài)變量$?

中2023年2月4日36exitn常見的返回狀態(tài)碼0:執(zhí)行正確1:通用錯誤126:命令或腳本沒有執(zhí)行權(quán)限127:命令沒找到2023年2月4日37$echo$$#顯示當(dāng)前進(jìn)程的PID9245$echo$?#顯示在此之前執(zhí)行的命令的返回值0$bash#調(diào)用子Shell$echo$$#顯示當(dāng)前進(jìn)程的PID9474$exit1#指定返回值并返回父Shell$echo$?#顯示上一個Shell/腳本的返回值1$list#執(zhí)行不存在的命令bash:list:commandnotfound$echo$?127$touchbbb.sh$./bbb.sh#執(zhí)行不具有執(zhí)行權(quán)限的命令bash:./bbb.sh:Permissiondenied$echo$?126read從鍵盤輸入內(nèi)容為變量賦值read[-p

"信息"][var1var2...]若省略變量名,則將輸入的內(nèi)容存入REPLY變量結(jié)合不同的引號為變量賦值雙引號””:允許通過$符號引用其他變量值單引號’’:禁止引用其他變量值,$視為普通字符反撇號

``

:將命令執(zhí)行的結(jié)果輸出給變量更多read的用法參見/guide/Getting_User_Input_Via_Keyboard2023年2月4日38read舉例2023年2月4日39#!/bin/bash#Thisscriptistotesttheusageofread#Scriptname:ex4read.shecho"===examplesfortestingread==="echo-e

"Whatisyourname?\c"readnameecho"Hello$name"echoecho-n"Wheredoyouwork?"readecho"Iguess$REPLYkeepsyoubusy!"echoread-p

"Enteryourjobtitle:"echo"Ithoughtyoumightbean$REPLY."echoecho"===Endofthescript==="只讀變量舉例[lrj@centos1~]$myname=Osmond[lrj@centos1~]$echo$mynameOsmond[lrj@centos1~]$readonlymyname[lrj@centos1~]$unsetmyname-bash:unset:myname:cannotunset:readonlyvariable[lrj@centos1~]$myname="OsmondLiang"-bash:myname:readonlyvariable[lrj@centos1~]$2023年2月4日梁如軍(linuxbooks@126.com)CreativeCommonsLicense(BY-NC-SA)40只讀變量readonlyvariable是指不能被清除或重新賦值的變量。同時輸出多行信息使用echo使用herefile2023年2月4日41echo

"Line1Line2Line3"cat<<_END_Line1Line2Line3_END_多行內(nèi)容中不能出現(xiàn)雙引號,否則echo

提前結(jié)束若確實(shí)需要使用雙引號,需使用轉(zhuǎn)義字符:\"_END_可以是任意字符串,只要上下一致即可多行內(nèi)容中不能出現(xiàn)內(nèi)容為_END_開始的行,否則cat提前結(jié)束整數(shù)運(yùn)算Bash變量沒有嚴(yán)格的類型定義本質(zhì)上Bash變量都是字符串若一個字面常量或變量的值是純數(shù)字的,不包含字母或其他字符,Bash可以將其視為長整型值,并可做算數(shù)運(yùn)算和比較運(yùn)算。Bash也允許顯式地聲明整型變量declare-i變量名2023年2月4日42算數(shù)運(yùn)算符2023年2月4日43+、-、*、/(四則運(yùn)算)**、%(冪運(yùn)算和模運(yùn)算,取余數(shù))<<、>>(按位左移和按位右移)&、^、|(按位與、按位異或和按位或)=、+=、-=、*=、/=、%=

<<=、>>=、&=、^=、|=(賦值運(yùn)算)<、>、<=、>=、==、!=(比較操作符)&&、||(邏輯與和邏輯或)注:按位運(yùn)算是以二進(jìn)制形式進(jìn)行的。算術(shù)運(yùn)算擴(kuò)展2023年2月4日44$[expression]

$((expression))num1=$[4+1];echo

$num1num1=$(($num1*2-3));echo

$num1注意${···},$(···),$[···],$((···))

的不同作用用$[···],$((···))

進(jìn)行整數(shù)運(yùn)算時,括號內(nèi)變量前的美元符號$可以省略。((num2=2+3**2-1001%5));echo

$num2num2=$((2+3**2-1001%5));echo

$num2echo

$((2+3**2-1001%5))Shell內(nèi)置命令——letlet內(nèi)置命令用于算術(shù)運(yùn)算2023年2月4日45num2=1;echo

$num2letnum2=4+1;echo

$num2letnum2=$num2+1;echo

$num2賦值符號和運(yùn)算符兩邊不能留空格!如果將字符串賦值給一個整型變量時,則變量的值為0如果變量的值是字符串,則進(jìn)行算術(shù)運(yùn)算時設(shè)為0letnum2=4+1let"num2=4+1"#

用引號忽略空格的特殊含義用let

命令進(jìn)行算術(shù)運(yùn)算時,最好加雙引號。expr通用的表達(dá)式計算命令表達(dá)式中參數(shù)與操作符必須以空格分開。表達(dá)式中的運(yùn)算可以是算術(shù)運(yùn)算,比較運(yùn)算,字符串運(yùn)算和邏輯運(yùn)算。2023年2月4日46manexprexpr5%3expr5\*3#乘法符號必須被轉(zhuǎn)義expr2+5\*2-3%2expr

\(2+5\)\*2–3#括號必須被轉(zhuǎn)義浮點(diǎn)數(shù)運(yùn)算bash

只支持整數(shù)運(yùn)算可以通過使用bc

awk

工具來處理浮點(diǎn)數(shù)運(yùn)算2023年2月4日47n=$(echo"scale=3;13/2"|bc)echo

$nm=`awk'BEGIN{x=2.45;y=3.123;\printf"%.3f\n",x*y}'`echo

$mprintf命令2023年2月4日48

printf

可用來按指定的格式輸出變量printfformat輸出參數(shù)列表printf"%-12.5f\n"123.456format

以%開頭flagfieldwidthprecision格式符-:左對齊+:輸出符號0:空白處添0空格:前面加一空格字段寬度小數(shù)點(diǎn)后輸出位數(shù)printf命令(續(xù))2023年2月4日49printf

命令的格式說明符c字符型g/G浮點(diǎn)數(shù)(自動)d十進(jìn)制整數(shù)o八進(jìn)制e/E浮點(diǎn)數(shù)(科學(xué)計數(shù)法)s字符串f浮點(diǎn)數(shù)(小數(shù)形式)x/X十六進(jìn)制format

中還可以使用\a警鈴\t水平制表符\b退后一格\v垂直制表符\n換行\(zhòng)\反斜杠\f換頁\”雙引號\r回車%%百分號printf命令舉例2023年2月4日50printf"Thenumberis:%.2f\n"100printf"%-20s|%12.5f|\n""Joy"10printf"%-10d%010o%+10x\n"202020printf"%6d\t%6o\"%6x\"\n"202020例:數(shù)組變量2023年2月4日51

Bash

2.x

以上支持一維數(shù)組,下標(biāo)從0開始。variable=(item1item2item2...)variable[n]=valuedeclare

-a

variablevariable=(item1item2item2...)數(shù)組的引用${variable[n]}使用declare

聲明或直接給變量名加下標(biāo)來賦值。數(shù)組變量舉例2023年2月4日52declare

-a

stustu=(math1101math1102math1103)echo${stu[0]}

#列出stu的第一個元素echo${stu[*]}

#列出stu的所有元素echo${#stu[*]}

#給出數(shù)組stu中元素的個數(shù)數(shù)組與數(shù)組元素的刪除unsetstu[1]#刪除stu的第二個元素unsetstu#刪除整個數(shù)組數(shù)組賦值時無須按順序賦值x[3]=100;echo${x[*]}state=(ME[3]=CA[2]=NT);echo${state[*]}Shell內(nèi)置命令——declare2023年2月4日53內(nèi)置命令declare可用來聲明變量。declare[選項(xiàng)]

variable[=value]選項(xiàng)含義-r將變量設(shè)為只讀(

readonly

)-x將變量輸出到子shell中(export

為全局變量)-i將變量設(shè)為整型(integer

)-a將變量設(shè)置為一個數(shù)組(array

)-f列出函數(shù)的名字和定義(

function

)-F只列出函數(shù)名declare舉例2023年2月4日54declare–r

myname=osmondunsetmynamedeclaremyname=“OsmondLiang"declare–x

myname2=lrjmyname2=lrjdeclare–x

myname2declaredeclaremyname=osmond例:變量及相關(guān)命令小結(jié)12023年2月4日55echo$variable

或echo${variable}unset

variablesetreadonlyvariableexportvariable=valueexport-nvariableexport-pdeclare[選項(xiàng)]

variable=value變量及相關(guān)命令小結(jié)22023年2月4日56basenamedirnamelet或expr${var:-word}、${var:=word}、${var:?word}、${var:+word}$0、$1-$9、${n}、$#、$*、$@、$$、$!、$?、$-evalnewstr=\$$str2

、newstr=${!str2}`hostname`、$(hostname)`basename\`pwd\``、$(basename$(pwd))$[expression]

、$((expression))變量及相關(guān)命令小結(jié)32023年2月4日57

輸入readvar1var2...readread–p

"提示"輸出printf"%-12.5f\t%d\n"123.458format

以%開頭flagfieldwidthprecision格式符-:左對齊+:輸出符號0:空白處添0空格:前面加一空格字段寬度小數(shù)點(diǎn)后輸出位數(shù)cdefgsox\b\n\r\t\v\\\”%%REPLYREPLY輸出參數(shù)用空格隔開條件測試2023年2月4日58條件測試簡介條件測試可以判斷某個特定條件是否滿足測試之后通常會根據(jù)不同的測試值選擇執(zhí)行不同任務(wù)條件測試的種類命令成功或失敗表達(dá)式為真或假條件測試的值Bash中沒有布爾類型變量退出狀態(tài)為0表示命令成功或表達(dá)式為真非0則表示命令失敗或表達(dá)式為假狀態(tài)變量$?

中保存了退出狀態(tài)的值2023年2月4日59條件測試舉例(1)2023年2月4日60$

User=osmond$

grep^$User

/etc/passwd$

echo$?$

grep^$User

/etc/passwd>/dev/null\&&echo“$Userisauserin/etc/passwd.”\||echo“$Userisn’tauserin/etc/passwd.”$

Host=centos1$

ping–c1$Host$

echo$?$

ping–c1$Host>/dev/null\&&echo“$Hostisup.”\||echo“$Hostisdown.”條件測試語句語句格式1:test<測試表達(dá)式>格式2:

[<測試表達(dá)式>]格式3:

[[<測試表達(dá)式>]](bash

2.x

版本以上)說明格式1和格式2是等價的,格式3是擴(kuò)展的test命令在[[]]中可以使用通配符進(jìn)行模式匹配&&,||,

<,

和>能夠正常存在于[[]]中,但不能在

[]中出現(xiàn)[和[[之后的字符必須為空格,]和]]之前的字符必須為空格要對整數(shù)進(jìn)行關(guān)系運(yùn)算也可以使用(())進(jìn)行測試2023年2月4日61條件測試操作符條件測試表達(dá)式中可用的操作符文件測試操作符字符串測試操作符整數(shù)二元比較操作符使用邏輯運(yùn)算符2023年2月4日62文件測試2023年2月4日63[

-ffname

]fname

存在且是普通文件時,返回真(即返回0)[

-L

fname

]fname

存在且是鏈接文件時,返回真[

-d

fname

]fname

存在且是一個目錄時,返回真[

-e

fname

]fname(文件或目錄)存在時,返回真[

-s

fname

]fname

存在且大小大于0時,返回真[

-r

fname

]fname(文件或目錄)存在且可讀時,返回真[

-w

fname

]fname(文件或目錄)存在且可寫時,返回真[

-x

fname

]fname(文件或目錄)存在且可執(zhí)行時,返回真測試:文件是否存在,文件屬性,訪問權(quán)限等。

更多文件測試符參見test

的在線幫助mantest使用lftp同步y(tǒng)um倉庫2023年2月4日64#!/bin/bash##ScriptName:sync_iredmail_yum_repo.shDIST=5ARCH="i386"EXCL_ARCH="x86_64"SRC=/yum/rpms/$DIST/DST=/var/ftp/yum/repos/iredmail/$DIST/$ARCH/[!-e$DST]

&&mkdir-p$DSTexcludes="\"(${EXCL_ARCH})|(repodata)\""cd$DSTlftp-e"setmirror:exclude-regex$excludes&&\mirror--delete--only-newer--verbose&&exit"$SRCcreaterepo.>/dev/null使用reposync同步倉庫2023年2月4日65#!/bin/bash##ScriptName:sync_atomic-repo_with_reposync.shARCH="i386"url="/channels/atomic/centos/5"release="atomic-release-1.0-13.el5.art.noarch.rpm"rpm-U$url/$ARCH/RPMS/$releaserpm--import/etc/pki/rpm-gpg/RPM-GPG-KEY.art.txt使用reposync同步倉庫之前首先要配置倉庫安裝atomic-release的RPM包導(dǎo)入其RPM公鑰對yum和reposync使用不同的配置文件yum

使用本地倉庫配置以加快更新速度/etc/yum.conf和/etc/yum.repos.d/atomic.reporeposync使用運(yùn)程倉庫配置/etc/reposync.conf和/etc/yum/repos.d/atomic.repo使用reposync同步倉庫續(xù)12023年2月4日66[!-f/etc/reposync.conf]&&(cp/etc/yum.conf/etc/reposync.conf;echo"reposdir=/etc/yum.repos.d">>/etc/yum.conf;echo"reposdir=/etc/yum/repos.d">>/etc/reposync.conf;mkdir/etc/yum/repos.d;mv/etc/yum.repos.d/atomic.repo/etc/yum/repos.d;cat<<__END__>/etc/yum.repos.d/atomic.repo[atomic]name=CentOS/RedHatEnterpriseLinux\$releasever-baseurl=file:///var/ftp/yum/repos/atomic/centos/5/$ARCH/atomicenabled=1priority=1protect=0gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY.art.txtgpgcheck=1__END__)配置對yum和reposync使用不同的配置文件僅當(dāng)/etc/reposync.conf不存在時執(zhí)行一次(……)使用reposync同步倉庫續(xù)22023年2月4日67DST="/var/ftp/yum/repos/atomic/centos/5/$ARCH"[!-e$DST]

&&mkdir-p$DST||cd$DST/usr/bin/yumcleanall/usr/bin/reposync--arch=$ARCH--repoid=atomic\

-d-c/etc/reposync.confcdatomic/usr/bin/createrepo./usr/bin/yumcleanall若本地同步的目標(biāo)目錄不存在創(chuàng)建之,否則進(jìn)入之使用

reposync

同步倉庫的RPM文件-a,--arch:指定架構(gòu)(i386、x86_64)-r,--repoid:指定要同步的倉庫名-d,--delete:刪除本地存在而遠(yuǎn)程已經(jīng)不存在的文件-c,--config:指定reposync使用的配置文件使用createrepo創(chuàng)建倉庫(repodata)字符串測試2023年2月4日68[

-z

string

]如果字符串string長度為0,返回真[

-n

string

]如果字符串string長度不為0,返回真[

str1

=

str2

]兩字符串相等(也可使用==)返回真[

str1

!=

str2

]兩字符串不等返回真[[

str1

==

str2

]]兩字符串相同返回真[[

str1

!=

str2

]]兩字符串不相同返回真[[

str1

=~

str2

]]str2是str1的子串返回真[[

str1

>

str2

]]str1大于str2返回真[[

str1

<

str2

]]str1小于str2返回真字符串按從左到右對應(yīng)字符的ASCII碼進(jìn)行比較字符串的空值檢查2023年2月4日69[-z"$name"][!

"$name"][

"X${name}"

=

"X"][-n"$name"

]["$name"][

"X${name}"

!=

"X"]檢查空值檢查非空值[

"$name"

=

""]["$name"!=

""]整數(shù)測試(1)2023年2月4日梁如軍(linuxbooks@126.com)CreativeCommonsLicense(BY-NC-SA)70[

int1

-eq

int2

]

int1等于

int2返回真[

int1

-ne

int2

]

int1不等于

int2返回真[

int1

-gt

int2

]

int1大于

int2返回真[

int1

-ge

int2

]

int1大于或等于

int2返回真[

int1

-lt

int2

]

int1小于

int2返回真[

int1

-le

int2

]

int1小于或等于

int2返回真[[

int1

-eq

int2

]]

int1等于

int2返回真[[

int1

-ne

int2

]]

int1不等于

int2返回真[[

int1

-gt

int2

]]

int1大于

int2返回真[[

int1

-ge

int2

]]

int1大于或等于

int2返回真[[

int1

-lt

int2

]]

int1小于

int2返回真[[

int1

-le

int2

]]

int1小于或等于

int2返回真操作符兩邊必須留空格!整數(shù)測試(2)2023年2月4日71((int1==int2))

int1等于

int2返回真((int1!=int2))

int1不等于

int2返回真((int1

>

int2))

int1大于

int2返回真((int1

>=int2))

int1大于或等于

int2返回真((int1

<

int2))

int1小于

int2返回真((int1<=int2))

int1小于或等于

int2返回真操作符兩邊的空格可省略!條件測試舉例(2)2023年2月4日72$[$a!=$b];echo$?0$[[$a!=$b]];echo$?0$[$n-gt$m];echo$?1$[[$n>$m]];echo$?1$((n>m));echo$?1$(($n>$m));echo$?1$[[n>m]];echo$?0$a=linux;b=unix$n=5;m=7$[$a!=$b]&&echoT||echoFT$[[$a!=$b]]&&echoT||echoFT$[$n-gt$m]&&echoT||echoFT$[[$n>$m]]&&echoT||echoFF$((n>m))&&echoT||echoFF$(($n>$m))&&echoT||echoFF$[[n>m]]&&echoT||echoFT條件測試舉例(3)2023年2月4日73name=Tom;[-z$name];

echo$?name2=Andy;[$name

=$name2

]

;

echo$?name=Tom

[$name

=[Tt]??

]

echo$?name=Tom

[[$name

=[Tt]??

]]

echo$?方括號前后要留空格!x=1;[$x

-eq

1

];

echo$?x=a;[$x

-eq

1

];

echo$?XX[]內(nèi)不能使用通配符!邏輯測試2023年2月4日74[[

pattern1

&&

pattern2

]]邏輯與

[[

pattern1

||

pattern2

]]邏輯或

[[

!

pattern

]]邏輯非

[

expr1

-aexpr2

]邏輯與,都為真時,結(jié)果為真[

expr1

-o

expr2

]邏輯或,有一個為真時,結(jié)果為真[

!

expr

]邏輯非((

expr1

&&expr2

))邏輯與((

expr1

||

expr2

))邏輯或((

!

expr

))邏輯非條件測試舉例(4)2023年2月4日75[[$x=

1&&$name=To?

]];

echo$?x=1;name=Tom;[$x

-eq

1–a–n$name

];

echo$?注:不能隨便添加括號[

(

$x

-eq

1

)–a(

–n$name

)

];

echo$?X(($x==

1&&$name=To?

));

echo$?注:不能在(())中做字符串比較(($x==

1))

&&[[$name=To?

]];

echo$?此處的&&并非邏輯運(yùn)算符,而是命令聚合(CommandGroup)X流程控制——分支2023年2月4日76流程控制語句分支

if

條件語句

case

選擇語句循環(huán)

for

循環(huán)語句

while

循環(huán)語句

until

循環(huán)語句

select

循環(huán)與菜單2023年2月4日77循環(huán)控制break

語句continue

語句位置參數(shù)處理

shift

命令

getopts

命令分支結(jié)構(gòu)——if語句語法2023年2月4日78ifexpr1#如果expr1

為真(返回值為0)then#那么commands1#執(zhí)行語句塊commands1elif

expr2#若expr1

不真,而expr2

為真then#那么commands2#執(zhí)行語句塊commands2......

#可以有多個elif語句else#else最多只能有一個commands4#執(zhí)行語句塊commands4fi#

if語句必須以單詞fi

終止分支結(jié)構(gòu)——if語句說明2023年2月4日79

commands

為可執(zhí)行語句塊,如果為空,需使用shell

提供的空命令“:”,即冒號。該命令不做任何事情,只返回一個退出狀態(tài)0

if

語句可以嵌套使用

elif

可以有任意多個(0個或多個)

else

最多只能有一個(0個或1個)

if

語句必須以fi

表示結(jié)束

exprX

通常為條件測試表達(dá)式;也可以是多個命令,以最后一個命令的退出狀態(tài)為條件值。分支結(jié)構(gòu)——if語句流程1單分支:當(dāng)“條件成立”時執(zhí)行相應(yīng)的操作2023年2月4日80if

條件測試命令命令序列…fi

結(jié)束判斷條件為真then條件為假分支結(jié)構(gòu)——if語句舉例12023年2月4日81#!/bin/bash##filename:areyouok.shecho"AreyouOK?"readanswer#在if的條件判斷部分使用擴(kuò)展的test語句[[...]]#在[[]]中可以使用shell的通配符進(jìn)行條件匹配if[[$answer==[Yy]*||$answer==[Mm]aybe]]thenecho"Gladtohearit."fi分支結(jié)構(gòu)——if語句流程2雙分支:當(dāng)“條件成立”、“條件不成立”時分別執(zhí)行不同操作2023年2月4日82if

條件測試命令命令序列1…條件為真then命令序列2…條件為假elsefi

結(jié)束判斷分支結(jié)構(gòu)——if語句舉例22023年2月4日83#!/bin/bash##filename:test-host-up-or-down.sh#if的條件部分可以使用普通的命令進(jìn)行測試#當(dāng)命令正確執(zhí)行($?=0)返回真,否則($?<>0)返回假myhost=centos1.ls-al.meifping-c1-w2$myhost&>/dev/nullthen

echo"$myhostisUP."elseecho"$myhostisDOWN."fi分支結(jié)構(gòu)——if語句舉例32023年2月4日84#!/bin/bash##filename:idcheck.sh#purpose:checkuseridtoseeifuserisroot.#Onlyroothasauidof0.#Formatforidoutput:#uid=9496(ellie)gid=40groups=40#root'suid=0#id=`id|awk-F'[=(]''{print$2}'`#getuserIDecho"youruseridis:$id"if((id==0))#[$id-eq0]then

echo"youaresuperuser."elseecho"youarenotsuperuser."fi分支結(jié)構(gòu)——if語句流程3多分支:針對多個條件執(zhí)行不同操作2023年2月4日85if

條件測試命令1命令序列1…條件為真then命令序列n…條件為假elseelif

條件測試命令2命令序列2…條件為真then…………fi

結(jié)束判斷分支結(jié)構(gòu)——if語句舉例42023年2月4日86#!/bin/bash##filename:ask-age.shread-p"Howoldareyou?"age#使用Shell算術(shù)運(yùn)算符(())進(jìn)行條件測試if((age<0||age>120));

thenecho"Outofrange!"exit1fi

#使用多分支if語句if((age>=0&&age<13));

thenecho"Child!"elif((age>=13&&age<20));thenecho"Callan!"elif((age>=20&&age<30));

thenecho"PIII!"elif((age>=30&&age<40));

thenecho"PIV!"elseecho"SorryIasked."fi分支結(jié)構(gòu)——if語句舉例52023年2月4日87#!/bin/bash##filename:useronline.sh#if語句可以嵌套使用if[$#-eq1]#或[[$#==1]]或(($#==1))then

ifwho|grep$1>/dev/null

thenecho$1isactive.

elseecho$1isnotactive.

fi

else

echo"Usage:$0<username>"exit1fi分支結(jié)構(gòu)——if語句舉例62023年2月4日88#!/bin/bash##filename:decide_file_type.sh#if語句可以嵌套使用[$#-ne1]&&echo"Usage:$0<filename>";exit1file=$1if[-d$file]thenecho"$fileisadirectory"elif[-f$file]then

if[-r$file-a-w$file-a-x$file];then#if[[-r$file&&-w$file&&-x$file]];thenecho“Youhave(rwx)permissioonon$file."

fielseecho"$fileisneitherafilenoradirectory."fi分支結(jié)構(gòu)——case語句語法2023年2月4日89caseexpr

in#expr

為表達(dá)式,關(guān)鍵詞

in

不要忘!

pattern1)#若

expr

pattern1

匹配,注意括號

commands1

#執(zhí)行語句塊

commands1

;;#跳出

case

結(jié)構(gòu)

pattern2)#若

expr

pattern2

匹配

commands2#執(zhí)行語句塊

commands2

;;

#跳出

case

結(jié)構(gòu)

......

#可以有任意多個模式匹配

*)#若

expr

與上面的模式都不匹配

commands#執(zhí)行語句塊

commands

;;

#跳出

case

結(jié)構(gòu)

esac#case

語句必須以

esac

終止分支結(jié)構(gòu)——case語句說明2023年2月4日90每個命令塊的最后必須有一個雙分號,可以獨(dú)占一行,或放在最后一個命令的后面。所給的匹配模式pattern

中可以含有通配符和“|”。如果expr

沒有找到匹配的模式,則執(zhí)行缺省值“*)”后面的命令塊(類似于if

中的else);“*)”可以不出現(xiàn)。表達(dá)式expr

按順序匹配每個模式,一旦有一個模式匹配成功,則執(zhí)行該模式后面的所有命令,然后退出case。分支結(jié)構(gòu)——case語句流程2023年2月4日91caseexpr=模式1esac

結(jié)束分支命令序列1…;;有expr=模式2expr=其他值(*)默認(rèn)命令序列………無是否否命令序列2…;;有無是分支結(jié)構(gòu)—case語句舉例12023年2月4日92#!/bin/bash##filename:what-lang-do-you-like.shecho"Whatisyourpreferredscriptinglanguage?"echo"1)bash"echo"2)perl"echo"3)python"echo"4)ruby"echo"5)Idonotknow!"readlangcase$langin

1)echo"Youselectedbash";;

2)echo"Youselectedperl";;

3)echo"Youselectedpython";;

4)echo"Youselectedruby";;

5)exit

esac分支結(jié)構(gòu)—case語句舉例22023年2月4日93#!/bin/bash##filename:yesorno.shecho-n"Doyouagreewiththis?[yesorno]:"rea

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論