shell入门基础
1.建立和運行shell程序
什么是shell程序呢? 簡單的說shell程序就是一個包含若干行
shell或者linux命令的文件.
象編寫高級語言的程序一樣,編寫一個shell程序需要一個文本編輯器.如VI等.
在文本編輯環(huán)境下,依據(jù)shell的語法規(guī)則,輸入一些shell/linux命令行,形成一個完整
的程序文件.
執(zhí)行shell程序文件有三種方法
(1)#chmod +x file
(2)#sh file
(3)# . file
在編寫shell時,第一行一定要指明系統(tǒng)需要那種shell解釋你的shell程序,如:#! /bin/bash,
#! /bin/csh,/bin/tcsh,還是#! /bin/pdksh .
2.shell中的變量
(1)常用系統(tǒng)變量
$# :保存程序命令行參數(shù)的數(shù)目
$? :保存前一個命令的返回碼
$0 :保存程序名
$* :以("$1 $2...")的形式保存所有輸入的命令行參數(shù)
$@ :以("$1""$2"...)的形式保存所有輸入的命令行參數(shù)
(2)定義變量
shell語言是非類型的解釋型語言,不象用C++/JAVA語言編程時需要事先聲明變量.給一
個變量賦值,實際上就是定義了變量.
在linux支持的所有shell中,都可以用賦值符號(=)為變量賦值.
如:
abc=9 (bash/pdksh不能在等號兩側(cè)留下空格 )
set abc = 9 (tcsh/csh)
由于shell程序的變量是無類型的,所以用戶可以使用同一個變量時而存放字符時而存放
整數(shù).
如:
name=abc (bash/pdksh)
set name = abc (tcsh)
在變量賦值之后,只需在變量前面加一個$去引用.
如:
echo $abc
(3)位置變量
當運行一個支持多個命令行參數(shù)的shell程序時,這些變量的值將分別存放在位置變量里.
其中第一個參數(shù)存放在位置變量1,第二個參數(shù)存放在位置變量2,依次類推...,shell保留
這些變量,不允許用戶以令外的方式定義他們.同別的變量,用$符號引用他們.
3.shell中引號的使用方法
shell使用引號(單引號/雙引號)和反斜線("\")用于向shell解釋器屏蔽一些特殊字符.
反引號(")對shell則有特殊意義.
如:
abc="how are you" (bash/pdksh)
set abc = "how are you" (tcsh)
這個命令行把三個單詞組成的字符串how are you作為一個整體賦值給變量abc.
abc1='@LOGNAME,how are you!' (bash/pdksh)
set abc1='$LOGNAME,how are you!' (tcsh)
abc2="$LOGNAME,how are you!" (bash/pdksh)
set abc2="$LOGNAME,how are you!" (tcsh)
LOGNAME變量是保存當前用戶名的shell變量,假設(shè)他的當前值是:wang.執(zhí)行完兩條命令后,
abc1的內(nèi)容是:$LOGNAME, how are you!.而abc2的內(nèi)容是;wang, how are you!.
象單引號一樣,反斜線也能屏蔽所有特殊字符.但是他一次只能屏蔽一個字符.而不能屏蔽
一組字符.
反引號的功能不同于以上的三種符號.他不具有屏蔽特殊字符的功能.但是可以通過他將
一個命令的運行結(jié)果傳遞給另外一個命令.
如:
contents=`ls` (bash/pdksh)
set contents = `ls` (tcsh)
4.shell程序中的test命令
在bash/pdksh中,命令test用于計算一個條件表達式的值.他們經(jīng)常在條件語句和循環(huán)
語句中被用來判斷某些條件是否滿足.
test命令的語法格式:
test expression
或者
[expression]
在test命令中,可以使用很多shell的內(nèi)部操作符.這些操作符介紹如下:
(1)字符串操作符 用于計算字符串表達式
test命令 | 含義
-----------------------------------------
Str1 = str2 | 當str1與str2相同時,返回True
Str1! = str2| 當str1與str2不同時,返回True
Str | 當str不是空字符時,返回True
-n str | 當str的長度大于0時,返回True
-z str | 當str的長度是0時,返回True
-----------------------------------------
(2)整數(shù)操作符具有和字符操作符類似的功能.只是他們的操作是針對整數(shù)
test表達式 | 含義
---------------------------------------------
Int1 -eq int2|當int1等于int2時,返回True
Int1 -ge int2|當int1大于/等于int2時,返回True
Int1 -le int2|當int1小于/等于int2時,返回True
Int1 -gt int2|當int1大于int2時,返回True
Int1 -ne int2|當int1不等于int2時,返回True
-----------------------------------------
(3)用于文件操作的操作符,他們能檢查:文件是否存在,文件類型等
test表達式 | 含義
------------------------------------------------
-d file |當file是一個目錄時,返回 True
-f file |當file是一個普通文件時,返回 True
-r file |當file是一個刻讀文件時,返回 True
-s file |當file文件長度大于0時,返回 True
-w file |當file是一個可寫文件時,返回 True
-x file |當file是一個可執(zhí)行文件時,返回 True
------------------------------------------------
(4)shell的邏輯操作符用于修飾/連接包含整數(shù),字符串,文件操作符的表達式
test表達式 | 含義
----------------------------------------------------------
! expr |當expr的值是False時,返回True
Expr1 -a expr2|當expr1,expr2值同為True時,返回True
Expr1 -o expr2|當expr1,expr2的值至少有一個為True時,返回True
-----------------------------------------------------------
注意:
tcsh shell 不使用test命令,但是tcsh中的表達式同樣能承擔相同的功能.tcsh
支持的表達式于C中的表達式相同.通常使用在if和while命令中.
tcsh表達式 | 含義
-------------------------------------------------------
Int1 <= int2 |當int1小于/等于int2時,返回True
Int1 >= int2 |當int1大于/等于int2時,返回True
Int1 < int2 |當int1小于int2時,返回True
Int1 > int2 |當int1大于int2時,返回True
Str1 == str2 |當str1與str2相同時,返回True
Str1 != str2 |當str1與str2不同時,返回True
-r file |當file是一個可讀文件時,返回True
-w file |當file是一個可寫文件時,返回True
-x file |當file是一個可執(zhí)行文件時,返回True
-e file |當file存在時,返回True
-o file |當file文件的所有者是當前用戶時,返回True
-z file |當file長度為0時,返回True
-f file |當file是一個普通文件時,返回True
-d file |當file是一個目錄時,返回True
Exp1 || exp2 |當exp1和exp2的值至少一個為True時,返回True
Exp1 && exp2 |當exp1和exp2的值同為True時,返回True
! exp |當exp的值為False時,返回True
5.條件語句
同其他高級語言程序一樣,復(fù)雜的shell程序中經(jīng)常使用到分支和循環(huán)控制結(jié)構(gòu),
bash,pdksh和tcsh分別都有兩種不同形式的條件語句:if語句和case語句.
(1)if語句
語法格式:
bash/pdksh用法:
if [expression1]
then
commands1
elif [expression2]
commands2
else
commands3
if
tcsh用法:
if (expression1) then
commands1
else if (expression2) then
commands2
else
commands3
endif
含義:當expression1的條件為True時,shell執(zhí)行then后面的commands1命令;當
expression1的條件為false并且expression2的條件滿足為True時,shell執(zhí)行
commands2命令;當expression1和expressin2的條件值同為false時,shell執(zhí)行
commands3命令.if語句以他的反寫fi結(jié)尾.
(2)case語句
case語句要求shell將一個字符串S與一組字符串模式P1,P2,...,Pn比較,當S與
某個模式Pi想匹配時,就執(zhí)行相應(yīng)的那一部分程序/命令.shell的case語句中字符
模式里可以包含象*這樣的通配符.
語法格式:
bash/pdksh用法:
case string1 in
str1)
commands1;;
str2)
commands2;;
*)
commands3;;
esac
tcsh用法:
switch (string1)
case str1:
statements1
breaksw
case str2:
statements2
breaksw
default:
statements3
breaksw
endsw
含義:shell將字符串string1分別和字符串模式str1和str2比較.如果string1與str1匹配,則
shell執(zhí)行commands1的命令/語句;如果string11和str2匹配,則shell執(zhí)行commands2的命令/
語句.否則shell將執(zhí)行commands3的那段程序/命令.其中,每個分支的程序/命令都要以兩個
分號(;;)結(jié)束.
6.循環(huán)語句
當需要重復(fù)的某些操作時,就要用到循環(huán)語句.
(1)for語句
大家知道在很多編程語言中for語句是最常見.在shell中也不例外.for語句要求shell將包含
在這個語句中的一組命令連續(xù)執(zhí)行一定的次數(shù).
語法格式:
bash/pdksh
用法1:
for var1 in list
do
commands
done
含義:在這個for語句中,對應(yīng)于list中的每個值,shell將執(zhí)行一次commands代表的一組命令.
在整個循環(huán)的每一次執(zhí)行中,變量var1將依此取list中的不同的值.
用法2:
for var1
do
setatements
done
含義:在這個for語句中,shell針對變量var1中的每一項分別執(zhí)行一次statements代表的一組
命令.當使用這種形式的語句時,shell認為var1變量中包含了所有的位置變量,而位置變量中
存放著程序的命令行參數(shù)值.也就是說,他等價于下列形式:
for var1 in " $@"
do
statements
done
tcsh用法:
在tcsh中沒有for這個單詞,與for語句起同樣功能的是foreach語句
foreach name (list)
commands
end
舉例:
for file ;bash/pdksh
do
tr a-z A-Z<$file>file.caps
done
# ;tcsh
foreach file ( $ * )
tr a-z A-Z<$file>$file.caps
end
(2)while語句
while語句是shell提供的另一種循環(huán)語句. while語句指定一個表達式和一組命令.這個
語句使得shell重復(fù)執(zhí)行一組命令,直到表達式的值為False為止.
語法格式:
while expression ?
do
statements
done
while (expression) ;tcsh
statements
end
舉例:
count=1 ;bash
while [ -n "$ *"] ***
do
echo "this is a parameter number $count $1"
shift
count='expr $count + 1'
done
set count = 1 ;tcsh
while ( " $ * " ! = "")
echo "this is a parameter number $count $1"
shift
set count = 'expr $count + 1'
end
語句中shift命令的功能是將所有的命令行參數(shù)依次相左傳遞.
(3)until語句
until與while語句具有類似的語法格式和功能,不同的是while中expression的值為True時,
shell執(zhí)行命令組;而until中當expression的值為False時,shell才執(zhí)行那組命令.
語法格式:
until expression
do
commands
done
舉例:
count=1
until [ -z " $ * "] ***
echo "this is a parameter number $count $1"
shift
count='expr $count + 1'
done
情注意上述例子中帶***號.在while中的表達式: -n string,他的含義是當string不是空
字符串時,表達式的值為True;在until中的表達式: -z string,他的 含義是當string是空
字符串時,表達式的值為True.由此可見,兩個程序?qū)l件表達式的設(shè)置恰好是相反的.
(4)shift語句
bash和tcsh都支持shift命令.shift將存放在位置變量中的命令行參數(shù),依次向左傳遞.例如
位置變量當前值為:
$1=file1 $2=file2 $3=file3
執(zhí)行一次shift命令后,位置變量的值為:
$1=file2 $2=file3
還可以在shift命令中指定位置變量轉(zhuǎn)移的次數(shù), 如:
shift n
例子:
while [ "$1"]
do
if [ "$1"="-i"] then
infile=" $2"
shift 2
else if [ "$1"="-o"] then
outfile="$2"
shift 2
else
echo "Program $0 does not recognize option $1"
fi
done
tr a-z A-Z<$infile>$outfile
(5)select語句
select語句是pdksh提供的一個獨特的循環(huán)語句.他不同于前面介紹的循環(huán)語句.他不是
反復(fù)計算一個條件表達式,并依據(jù)表達式的值決定是否執(zhí)行一組命令.select的功能是自動的
生成一個簡單的文本菜單.
語法格式:
select menu [in list_of_items]
do
commands
done
含義:當執(zhí)行一個select語句時,pdksh分別為每個列在list_of_items中的成員建立一個菜單
選項.list_of_items既可以是一個包含多個選項的變量,也可以是直接列在程序中的一組選項
.如果語句中沒有提供list_of_items,select語句將使用位置變量作為list_of_items.
舉例:
select menuitem in pick1 pick2 pick3
do
echo "are you sure you want to pick $menuitem"
read res ;接收用戶的輸入,并且將輸入的值存放在特定變量里.
if [ $res=" y" -o $res=" Y"]
then
break ;用于退出while,for,select等循環(huán)語句
fi
done
(6)repeat語句
repeat語句是tcsh提供的獨有的循環(huán)語句.使用repeat命令要求shell對一個命令執(zhí)行一定
的次數(shù).
語法格式:
repeat count command
如;
foreach num ( $ *)
repeat $num echo -n " *"
echo " "
end
7.shell中的函數(shù)
shell允許用戶定義自己的函數(shù).函數(shù)是高級語言中的重要結(jié)構(gòu).shell中的函數(shù)于C或者其他
語言中定義的函數(shù)一樣.與從頭開始,一行一行地寫程序相比,使用函數(shù)主要好處是有利于組織
整個程序.在bash中,一個函數(shù)的語法格式如下:
fname (){
shell comands
}
定義好函數(shù)后,需要在程序中調(diào)用他們.bash中調(diào)用函數(shù)的格式:
fname [parm1 parm2 parm3...]
調(diào)用函數(shù)時,可以向函數(shù)傳遞任意多個參數(shù).函數(shù)將這些參數(shù)看做是存放他的命令行參數(shù)的
位置變量.
舉例:
這個程序定義了4個函數(shù):
upper ():將傳遞給他的文件中的字母轉(zhuǎn)換成大寫,并存放到同名的結(jié)尾為.out的文件中.
lower ():將傳遞給他的文件里的字母轉(zhuǎn)換成小寫,并存放到同名的結(jié)尾為.out的文件中.
print ():輸出傳遞給他的文件的內(nèi)容.
usage_error ():輸出程序的幫助信息.
程序的主模塊是個case條件語句,他根據(jù)命令行中第一個參數(shù),決定程序要完成的功能,并調(diào)用相應(yīng)
的函數(shù)完成這一功能.
upper (){
shift
for i
do
tr a-a A-Z<$!>$1.out
rm $1
mv $1.out $1
shift
done; }
lower () {
shift
for i
do
tr A-Z a-z<$1>$1.out
rm $1
mv $1.out $1
shift
done; }
print() {
shift
for i
do
lpr $1
shift
done; }
usage_error() {
echo " $1 syntax is $1"
echo ""
echo " where option is one of the following"
echo " p--to print frame files"
echo " u--to save as uppercase"
echo " l--to save as lowercase";}
case $1 in
p | -p)print $@;;
u | -u)upper $@;;
l | -l)lower $@;;
*) usage_error $0;;
esac
------------------------------------------------------------------------------
總結(jié)
利用shell編程是提高系統(tǒng)管理工作效率的重要手段,學好shell跟了解系統(tǒng)基本命令和管理
工具的使用方法同樣重要!
附:
A.bash中常用的命令
命令 | 含義
-------------------------------------------------------------------------------
Alias |設(shè)置命令別名
Bg |將一個被掛起的進程在后臺執(zhí)行
cd |改變用戶的當前目錄
exit |終止一個shell
export |使作為這個命令的參數(shù)的變量及其當前值,在當前運行的shell的子進程中可見
fc |編輯當前的命令行歷史列表
fg |讓一個被掛起的進程在前臺執(zhí)行
help |顯示bash內(nèi)部命令的幫助信息
history |顯示最近輸入的一定數(shù)量的命令行
kill |終止一個進程
pwd |顯示用戶當前工作目錄
unalias |刪除命令行別名
--------------------------------------------------------------------------------
B.bash中常用的系統(tǒng)變量
變量 | 含義
-------------------------------------------------------------------------------
EDITOR,FCEDIT |Bash的fc命令的默認文本編輯器
HISTFILE |規(guī)定存放最近輸入命令行文件的名字
HISTSIZE |規(guī)定命令行歷史文件的大小
HOME |當前用戶的宿主目錄
OLDPWD |用戶使用的前一個目錄
PATH |規(guī)定bash尋找可執(zhí)行文件時搜索的路徑
PS1 |命令行環(huán)境中顯示第一級提示符號
PS2 |命令行環(huán)境中顯示第二級提示符號
PWD |用戶當前工作目錄
SECONDS |當前運行的bash進程的運行時間(以秒為單位)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.??????? 學習提示
學習shell主要在于用,光看書沒用
2.??????? 單引號、雙引號、括號、花括號及反引號
單引號內(nèi)所有元字符都失去特殊含義(包括\)雙引號內(nèi)除了變量域($)和命令域(`)以外的元字符都失去特殊含義,所以一般使用雙引號引用
花括號{}被用來區(qū)分變量名和周圍的文本:echo ${file} and $file1 尋找變量file,file1
命令替代的格式:反引號來環(huán)繞一個命令象` cmd `,它和$(command) 是等價的:ls -l `find . -type f`
3.??????? 取行
sed -n "3"p file 取第3行
sed -n "1,3"p file 取第1到3行
sed -n "1,$"p file 取第1到最后一行
sed -n "1,$num"p file 取第1到num行
sed -n "\$p" file 取最后1行
sed -e '1!G;h;$!d' file倒過來顯示
4.??????? sed 附加/替換:
sed "/xmdh/a\daoyou" file 把含有xmdh的行的結(jié)尾附加daoyou(有換行)
sed 's/$/ daoyou/' file把每行的結(jié)尾附加daoyou(在同一行)
sed '/test/s/$/ daoyou/' file把包含test行的結(jié)尾附加daoyou(在同一行)
sed '10s/$/ daoyou/' file把第10行的結(jié)尾附加daoyou(在同一行)
?
sed "s/xmdh/daoyou/g" file把xmdh替換成daoyou
sed?"s/xmdh/daoyou/;G"?file把xmdh替換成daoyou并增加一個換行
cat userlog |sed -n '/xmdh/ w test.txt'查看含有xmdh并寫入test.txt中
5.??????? 搜索:
vi file 后:/\<daoyou\>/
6.??????? 顯示行號:
awk '/dhshunde/{print NR,$0}' userlog或grep -n dhshunde userlog 顯示含有dhshunde的行號及內(nèi)容
cat userlog |sed -n ‘/erptest/=’ 顯示含有erptest的行號
cat userlog |sed -n '/xmdh/p'|sed -n '$p' 顯示包含xmdh的最后一行
7.??????? awk中使用變量
/bin/cat /etc/ppp/chap-secrets|grep $5|awk '{print logouttime"\t","username:"$1"\t","logout""\t","data:"datasize}' logouttime="`/bin/date`" datasize="$size" >>$pptplogdirectory/userlog(注:size前面已經(jīng)有定義)
8.??????? Find的用法
注:f i n d命令將所有匹配到的文件一起傳遞給e x e c執(zhí)行,而x a rg s命令每次只獲取一部分文件而不是全部,所以exec有長度限制,文件不能太多,否則會產(chǎn)生溢出錯誤,而xargs則沒有
find . -mtime -1 –print 跟現(xiàn)在小于1天修改的文件
find . -perm 755 –print 顯示具有755屬性的文件
find . -size +1000000c –print 查找大于1M的文件
find . -type f -exec ls -l {} \; 查找文件并列表顯示(注:{}與\之間有空格,最后有;)
find . -type f -exec rm?{} \;查找文件并刪除
find . -type f -print |xargs ls –l查看文件并列表顯示
find / ?\( -perm -4000 -o -perm -2000 \) -type f –print 查找SUID和SGID文件
9.??????? 向登錄終端用戶發(fā)送消息
echo "hello I am jiangdaoyou"|tee /dev/pts/2 (tty可以查看自已的終端號),等同于:write root pts/2然后輸入:hello I am jiangdaoyou然后Ctrl+D結(jié)束
10.?? awk之BEGIN和END
即在文件頭增加列名:
cat userlog |awk 'BEGIN{print "Time username\n-----------------"};{print $4,$7}'
Time???? username
------------------------------
15:19:28 username:xmdh
15:20:00 username:xmdh
將在上面的基礎(chǔ)上增加結(jié)尾說明“end of report!!!!”
cat userlog |awk 'BEGIN{print "Time???? username\n-----------------"}{print $4,$7}END{print "end of report!!!!"}'
?
11.?? 截取/轉(zhuǎn)化字符
echo "200604211031"|cut -c9-12 得到1031
cat test.ok |tr 'arp' 'rpm' 把arp轉(zhuǎn)為rpm
12.?? 求平均值
vmstat 1 4|awk '{print $4}'|grep -o '[0-9]*'|sed 's/,//g' |awk '{total=total+$1;if(NR%4= =0) {print total/4}}'或如下方法:
vmstat 1 4|awk 'NR>2{sum+=$4}END{print sum/4}'
13.?? 循環(huán)
ls |for file in *;do echo "rpm -ivh" $file;done
ls |for file in $(ls *.rpm);do echo "rpm -ivh" $file;done
===============================================================================
好久沒有碰shell編程了,都忘了,現(xiàn)在回顧一下 1.變量賦值a=123
read name
b=$(ls /home) 把命令的執(zhí)行結(jié)果賦值給變量
2.使用變量(前面用$)
echo $a
let a=a+1
系統(tǒng)變量
CODE: $0 這個程序的執(zhí)行名字
$n 這個程序的第n個參數(shù)值,n=1...9
$* 這個程序的所有參數(shù)
$# 這個程序的參數(shù)個數(shù)
$$ 這個程序的PID
$! 執(zhí)行上一個背景指令的PID
$? 上一個指令的返回值 3.if語句
CODE: if [ "22" -lt "33" ]注意空格
then
echo "22 less than 33"
else
echo "no"
fi 4.case語句
CODE: #!/bin/bash
echo "enter a number"
read ans
case $ans in
1)
echo??"you numer is $ans"
;;
2)
echo "you number is 2"
;;
[3-9])
echo "you number is $ans"
esac
case語句
case語句要求shell將一個字符串S與一組字符串模式P1,P2,...,Pn比較,當S與
某個模式Pi想匹配時,就執(zhí)行相應(yīng)的那一部分程序/命令.shell的case語句中字符
模式里可以包含象*這樣的通配符.
語法格式:
bash用法:
case string1 in
str1)
commands1;;
str2)
commands2;;
*)
commands3;;
esac
?
5.比較運算符運算符? ? ? ? 描述? ? ? ? 示例
文件比較運算符
-e filename ? ? ? ? 如果 filename 存在,則為真? ? ? ? [ -e /var/log/syslog ]
-d filename ? ? ? ? 如果 filename 為目錄,則為真? ? ? ? [ -d /tmp/mydir ]
-f filename ? ? ? ? 如果 filename 為常規(guī)文件,則為真? ? ? ? [ -f /usr/bin/grep ]
-L filename ? ? ? ? 如果 filename 為符號鏈接,則為真? ? ? ? [ -L /usr/bin/grep ]
-r filename ? ? ? ? 如果 filename 可讀,則為真? ? ? ? [ -r /var/log/syslog ]
-w filename ? ? ? ? 如果 filename 可寫,則為真? ? ? ? [ -w /var/mytmp.txt ]
-x filename ? ? ? ? 如果 filename 可執(zhí)行,則為真? ? ? ? [ -L /usr/bin/grep ]
filename1 -nt filename2 ? ? ? ? 如果 filename1 比 filename2 新,則為真? ? ? ? [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2 ? ? ? ? 如果 filename1 比 filename2 舊,則為真? ? ? ? [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比較運算符 (請注意引號的使用,這是防止空格擾亂代碼的好方法)
-z string ? ? ? ? 如果 string 長度為零,則為真? ? ? ? [ -z "$myvar" ]
-n string ? ? ? ? 如果 string 長度非零,則為真? ? ? ? [ -n "$myvar" ]
string1 = string2? ? ? ? 如果 string1 與 string2 相同,則為真? ? ? ? [ "$myvar" = "one two three" ]
string1 != string2? ? ? ? 如果 string1 與 string2 不同,則為真? ? ? ? [ "$myvar" != "one two three" ]
算術(shù)比較運算符
num1 -eq num2? ? ? ? 等于? ? ? ? [ 3 -eq $mynum ]
num1 -ne num2? ? ? ? 不等于? ? ? ? [ 3 -ne $mynum ]
num1 -lt num2? ? ? ? 小于? ? ? ? [ 3 -lt $mynum ]
num1 -le num2? ? ? ? 小于或等于? ? ? ? [ 3 -le $mynum ]
num1 -gt num2? ? ? ? 大于? ? ? ? [ 3 -gt $mynum ]
num1 -ge num2? ? ? ? 大于或等于? ? ? ? [ 3 -ge $mynum ]
6.while語句 語法格式:
while expression?
do
statements
done
輸出<10的基數(shù)
| #!/bin/bash |
for循環(huán)有幾種方式:
1.for name [ in word ] ; do list ; done
2.for (( expr1 ; expr2 ; expr3 )) ; do list ; done//注意有2層括號
其中l(wèi)ist簡單說就是一串由操作符(operator ;、&、&&、||)分隔開的管道(pipeline)序列,詳情參看man bash
各給出一個簡單例子:
for filename in `ls`
do
cat $filename
done
2.
for((i=0; i<10; i++))
do
echo $i
done
1.條件變量替換:
Bash Shell可以進行變量的條件替換,既只有某種條件發(fā)生時才進行替換,替換
條件放在{}中.
(1) ${value:-word}
當變量未定義或者值為空時,返回值為word的內(nèi)容,否則返回變量的值.
(2) ${value:=word}
與前者類似,只是若變量未定義或者值為空時,在返回word的值的同時將
word賦值給value
(3) ${value:?message}
若變量以賦值的話,正常替換.否則將消息message送到標準錯誤輸出(若
此替換出現(xiàn)在Shell程序中,那么該程序?qū)⒔K止運行)
(4) ${value:+word}
若變量以賦值的話,其值才用word替換,否則不進行任何替換
(5) ${value:offset}
${value:offset:length}
從變量中提取子串,這里offset和length可以是算術(shù)表達式.
(6) ${#value}
變量的字符個數(shù)
(7) ${value#pattern}
${value##pattern}
去掉value中與pattern相匹配的部分,條件是value的開頭與pattern相匹配
#與##的區(qū)別在于一個是最短匹配模式,一個是最長匹配模式.
(8) ${value%pattern}
${value%%pattern}
于(7)類似,只是是從value的尾部于pattern相匹配,%與%%的區(qū)別與#與##一樣
(9) ${value/pattern/string}
${value//pattern/string}
進行變量內(nèi)容的替換,把與pattern匹配的部分替換為string的內(nèi)容,/與//的區(qū)
別與上同
注意:上述條件變量替換中,除(2)外,其余均不影響變量本身的值
2.變量的算術(shù)運算
在Bash Shell中,只能進行兩個整數(shù)間的運算,其結(jié)果仍為整數(shù).要進行算術(shù)
運算,需要使用let命令,語法為:
let expr
expr是一個包含項和操作符的表達式,項可以是一個變量或是一個整數(shù)常數(shù),
當使用整數(shù)常數(shù)時,其默認為十進制整數(shù),用戶可以用radio#number來指定其它
形式的整數(shù),其中radio定義了整數(shù)是幾進制表示的,number是該整數(shù)的值.若
radio>10,那么數(shù)字字符可從0-9和A-Z.
在表達式中支持的操作符及其含義為:
+,-,*,/,% 加,減,乘,除,取模
>>,<<,&,^,| 左移,右移,位與,位異或,位或
?: 三元運算符.與C語言中的定義一致
~ 取補碼
!,>=,<=,>,<,==,!=,&&,||
=,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=
表達式式中也可以使用括號.括號或運算優(yōu)先級的定義與一般計算機語言中的
相同.
let命令具有返回值.當計算結(jié)果(若有多個表達式時,以最后一個為準)為0時,
返回值為1,否則為0.
當表達式中含有shell的特殊字符(如|)時,需要用引用符('或")將其引用起來.
使用let時還需要注意的時,對于let x+y這樣的式子,shell雖然計算了x+y的值
但卻將結(jié)果丟棄,若不想這樣,可以使用let sum=x+y將x+y的結(jié)果保存在變量sum中
另外還可以使用((和))操作符取代let命令,而且這樣的話,還可以省去對算術(shù)
表達式的引用,如果想返回表達式的值,則需用$(())的格式
使用set命令可以設(shè)置各種shell選項或者列出shell變量.單個選項設(shè)置常用的特性.
在某些選項之后-o參數(shù)將特殊特性打開.在某些選項之后使用+o參數(shù)將關(guān)閉某些特性,
不帶任何參數(shù)的set命令將顯示shell的全部變量.除非遇到非法的選項,否則set總是
返回ture.
當BASH shell被調(diào)用時,可以列出全部的選項.當前的選項集列在$-中.在option參數(shù)
被處理后,其他的參數(shù)被賦值到位置參數(shù)中($1,$2,...,$n)
set [--abefhkmnptuvxldCHP] [-o option name] [arguments ...]
源碼:
選項 說明
-a 自動向已經(jīng)修改的變量或為導出后序命令的變量作出標志
-b 不是在原提示符之前,而是立即引發(fā)終止后臺任務(wù)的狀態(tài)表表
-e 如果命令帶非零值返回,立即退出
-f 禁止帶擴展名的路徑
-h 定義函數(shù)時,定位和存儲函數(shù)命令,當函數(shù)被執(zhí)行時,通常查詢
函數(shù)命令
-k 所有的關(guān)鍵詞參數(shù),而不只是那些命令名前的關(guān)鍵詞參數(shù),被放
在環(huán)境命令中
-m 監(jiān)視器模式,啟動任務(wù)控制.此選項默認支持系統(tǒng)shell交互.后
臺進程以單獨的進程組運行,在每次完成任務(wù)時顯示包含退出的
狀態(tài)行
-n 讀取命令但不執(zhí)行命令.通常監(jiān)查shell腳本的句法錯誤.交互
shell被忽略
-o option-name 選項名可以是下列之一:
選項 說明
allexport 同-a選項
braceexpand shell執(zhí)行花括號擴展,在默認情況下起作用
emacs 使用emacs風格命令行編輯接口.除非shell以-noline-editing
選項啟動,否則當shell交互時,通過默認啟動該選項
errexit 同-e選項
histexpand 同-H選項
ignoreeof 其結(jié)果是好像shell命令I(lǐng)GNOREEOF=10被執(zhí)行
interactive 允許單詞前帶#號,以使得在交互shell中忽略命令行的全部字符
-commands
monitor 同-m選項
noclobber 同-C選項
noexec 同-n選項
noglob 同-f選項
nohash 同-d選項
notify 同-b選項
nounset 同-u選項
physical 同-p選項
posix 改變BASH屬性以匹配標準,默認操作不同于POSIX1003.2標準
verbose 同-v選項
vi 使用vi風格的命令行編輯器
XTRACE 同-x選項,如果沒有給出選項名,顯示當前選項值
-p 打開特權(quán)模式(在此模式,$ENV文件被處理,不能從環(huán)境中繼承
shell函數(shù).如果是有效用戶ID而不是實用戶組則自動啟動.關(guān)閉
此選項將使得有效用戶和組IDs設(shè)置實用戶和組IDs)
-t 在讀取命令并執(zhí)行之后退出
-u 當執(zhí)行參數(shù)括展時,把非設(shè)置變量作為錯誤處理(如果擴展企圖
出現(xiàn)在非設(shè)置變量中,shell顯示錯誤信息.如果不是交互式,則
帶非凌值退出)
-v 輸入行被讀取時,顯示shell輸入行
-x 在每個簡單命令被擴展之后,顯示PS4擴展值,之后是要執(zhí)行的命令
-l 保存和恢復(fù)綁定在命令中的名稱
-d 禁止執(zhí)行查找散列命令(通常,命令被保存在散列表中,一旦被找到
就不再繼續(xù)查找)
-C 效果好像是執(zhí)行了noclobber=shell命令
-H 使用!風格的歷史替代(當shell交互時,在默認情況下,此選項有效)
-P 如果設(shè)置此參數(shù),當執(zhí)行改變目錄命令cd時,不遵循符號鏈接,而是
使用實際的目錄
-- 如果在選項后沒有參數(shù),不設(shè)置位置參數(shù).否則,即使一些參數(shù)以a
選項開始,也要把位置參數(shù)設(shè)置為argument
- 結(jié)束選項的信號,將引發(fā)其余的參數(shù)被賦值到位置參數(shù)中(-x和-v
選項被關(guān)閉.如果沒有argument,位置參數(shù)將保留未改變的參數(shù))
函數(shù)
函數(shù)的使用
BASH 是一個相對簡單的腳本語言,不過為了方便結(jié)構(gòu)化的設(shè)計,BASH 中也提供了函數(shù)定義的功能。BASH 中的函數(shù)定義很簡單,只要向下面這樣寫就可以了:
function my_funcname {
code block
}
或者
my_funcname() {
code block
}
上面的第二種寫法更接近于 C 語言中的寫法。BASH 中要求函數(shù)的定義必須在函數(shù)使用之前,這是和 C 語言用頭文件說明函數(shù)方法的不同。
更進一步的問題是如何給函數(shù)傳遞參數(shù)和獲得返回值。BASH 中函數(shù)參數(shù)的定義并不需要在函數(shù)定義處就制定,而只需要在函數(shù)被調(diào)用時用 BASH 的保留變量 $1 $2 ... 來引用就可以了;BASH 的返回值可以用 return 語句來指定返回一個特定的整數(shù),如果沒有 return 語句顯式的返回一個返回值,則返回值就是該函數(shù)最后一條語句執(zhí)行的結(jié)果(一般為 0,如果執(zhí)行失敗返回錯誤碼)。函數(shù)的返回值在調(diào)用該函數(shù)的程序體中通過 $? 保留字來獲得。下面我們就來看一個用函數(shù)來計算整數(shù)平方的例子:
#!/bin/bash
square() {
let "res = $1 * $1"
return $res
}
square $1
result=$?
echo $result
exit 0
1.函數(shù)聲明后的使用域是全局的
(誰知道怎么聲明為局部的,希望可以通知我)
2.默認情況下變量的聲明也是全局的
3.local語句在函數(shù)內(nèi)部使用作為局部變量,哪怕聲明的變量是數(shù)組
fun()
{
? ?local -a test
? ?fun2()
? ?{
? ? test[0]=...
? ? test[1]=...
? ? }
}
在實際應(yīng)用過程中
無論你怎么調(diào)用,你都無法獲取test數(shù)組的值
總結(jié)
- 上一篇: VS2005 宽字符 unicode字符
- 下一篇: 菜鸟教程之Microsoft Windo