?? 30分鐘搞定bash腳本編程.txt
字號(hào):
一個(gè)最簡(jiǎn)單的腳本
這篇指南將通過(guò)一些例子來(lái)幫助大家學(xué)習(xí)功能強(qiáng)大的shell腳本編程.
在這一節(jié)中我將學(xué)習(xí)一些簡(jiǎn)單的腳本,它將有利于你深入學(xué)習(xí)一些知識(shí)。
一個(gè)最經(jīng)典的Hello World程序
#!/bin/bash
echo Hello World
這個(gè)腳本只有二行,它的第一行這個(gè)腳本程序由那個(gè)程序來(lái)解釋.第二行只有一個(gè)簡(jiǎn)單的動(dòng)作,它的功能是在終端上打印出一行”Hello World” 。如果你測(cè)試著執(zhí)行這個(gè)命令時(shí)(./hello.sh),你將會(huì)得到一個(gè)command not found的信息,這種情況大部分可能是你的第一行#!/bin/bash這個(gè)程序有問(wèn)題,你一定要確保bash可以找到并且可用。(一般情況下你還要對(duì)這個(gè)腳本附一個(gè)可執(zhí)行權(quán)限)
#chmod u+x hello.sh
一個(gè)非常簡(jiǎn)單的備份腳本
#!/bin/bash
tar -cZf /var/my-backup.tgz /home/me/
在這個(gè)腳本中,它替換了上一個(gè)例子的將一行信息打印在終端上的功能,取爾代之的是一個(gè)備份/home目錄的tar備份命令。
關(guān)于重定向的一些信息
最基本的理論基礎(chǔ)
這里有對(duì)于三個(gè)文件的重定向定義: stdin(標(biāo)準(zhǔn)輸入), stdout(標(biāo)準(zhǔn)輸出) and stderr(標(biāo)準(zhǔn)錯(cuò)誤輸出) (std=standard).
基本上你可以
1. 重定向 stdout 到一個(gè)文件
2. 重定向 stderr 到一個(gè)文件
3. 重定向 stdout 到stderr
4. 重定向 stderr 到 stdout
5. 重定向 stderr 到 stdout 中并且成為一個(gè)文件
6. 重定向 stderr and stdout to stdout
7. 重定向 stderr and stdout to stderr
在Linux中 1代表 '標(biāo)準(zhǔn)輸出', 2代表’標(biāo)準(zhǔn)錯(cuò)誤’
標(biāo)準(zhǔn)輸出
這個(gè)例子將會(huì)使ls的顯示結(jié)果重定向到一個(gè)文件中.
ls -l > ls-l.txt
標(biāo)準(zhǔn)錯(cuò)誤
這個(gè)例子將會(huì)使grep命令在運(yùn)行過(guò)程中出現(xiàn)的錯(cuò)誤輸出到一個(gè)文件中
grep da * 2> grep-errors.txt
管道
這一節(jié)我們將解釋一個(gè)非常簡(jiǎn)單的并且你以后一定會(huì)用到的功能,它就是管道。
為什么大家都會(huì)用到管道?
管道可以使你非常方便的將一個(gè)程序的結(jié)果轉(zhuǎn)向到另外一個(gè)程序中。
一個(gè)sed的例子
這個(gè)例子使用了非常簡(jiǎn)單的管道功能:
ls -l | sed -e "s/[aeio]/u/g"
當(dāng)我們執(zhí)行以下命令后:首先ls –l會(huì)先執(zhí)行并且它會(huì)輸出結(jié)果信息但是如果它的后面跟是一個(gè)管道符的話,那么它就會(huì)將結(jié)果重新定向到sed這個(gè)程序中,sed使用了替換功能,所以這個(gè)例子執(zhí)行完會(huì),會(huì)將ls –l結(jié)果中所有含有aeio的英文單詞替換成單詞u.
通過(guò)另外的方法實(shí)現(xiàn)ls –l *.txt
也許這種方法不同于ls –l *.txt,但是它避免了出現(xiàn)一條 No Such file Or Directory這種信息。
ls -l | grep ".txt"
當(dāng)ls –l 執(zhí)行后,它會(huì)將程序結(jié)果輸出到grep這個(gè)程序中,并且去匹配.txt這條信息。
變量
你可在任何編程語(yǔ)言中使用變量,但是在腳本編程中它們是沒(méi)有類(lèi)型的,簡(jiǎn)稱(chēng)弱類(lèi)型編程語(yǔ)言,在這個(gè)變量中可以保含一個(gè)數(shù)字,一個(gè)字符串,一個(gè)單詞等。你并不需要聲明這個(gè)變量,它會(huì)在引用這個(gè)變量時(shí)創(chuàng)建它。
使用變量來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Hello World
#!/bin/bash
STR="Hello World!"
echo $STR
第二行建立一個(gè)STR的變量并且為其附了一個(gè)“Hello World”的字符串變量值。當(dāng)在這個(gè)變量前面加上一個(gè)$符號(hào)時(shí),我們就將會(huì)得到這個(gè)變量的值。
例子(一個(gè)使用變量的備份腳本)
#!/bin/bash
OF=/var/my-backup-$(date +%Y%m%d).tgz
tar -cZf $OF /home/me/
局部變量
局部變量的生命是有限的,請(qǐng)看下面的例子
#!/bin/bash
HELLO=Hello
function hello {
local HELLO=World
echo $HELLO
}
echo $HELLO
hello
echo $HELLO
條件語(yǔ)句
條件語(yǔ)句可以使你決定是完成一個(gè)運(yùn)作或是不去完成一個(gè)動(dòng)作時(shí),通過(guò)一些判斷來(lái)實(shí)現(xiàn),一般情況都是通過(guò)一些操作符來(lái)實(shí)現(xiàn)判斷。
條件語(yǔ)句可以有許多實(shí)現(xiàn)方法,最多的情況是基于if expression then 這種情況,也就是大家常常說(shuō)的if判斷語(yǔ)句。它的語(yǔ)法基本結(jié)構(gòu)如下:
if [expression];
then
code if 'expression' is true.
fi
一個(gè)最基本的使用if ...then的例子
#!/bin/bash
if [ "foo" = "foo" ]; then
echo expression evaluated as true
fi
這段代碼執(zhí)行if判斷,如果foo等于foo的話,那么你就會(huì)執(zhí)行then語(yǔ)句下的輸出語(yǔ)句,最后通過(guò)fi來(lái)結(jié)束,這里我要強(qiáng)調(diào)一點(diǎn),就是很多新手在輸入源碼時(shí)特別是在if 語(yǔ)句后面沒(méi)有空格,在大括號(hào)后面沒(méi)有空格,在等號(hào)兩邊沒(méi)有空格,這些都會(huì)制造出一些麻煩的。
一個(gè)簡(jiǎn)單的控制if .. then ...else
#!/bin/bash
if [ "foo" = "foo" ]; then
echo expression evaluated as true
else
echo expression evaluated as false
fi
6.4 通過(guò)變量進(jìn)行判斷控制
#!/bin/bash
T1="foo"
T2="bar"
if [ "$T1" = "$T2" ]; then
echo expression evaluated as true
else
echo expression evaluated as false
fi
7. 循環(huán)結(jié)構(gòu)
在這一節(jié)中,你將會(huì)學(xué)習(xí)for、while、until loops循環(huán)
對(duì)于for 循環(huán)它有一點(diǎn)不同于其他的編程語(yǔ)言,它有一點(diǎn)像VB中的for each語(yǔ)句,就是所謂的遞歸的循環(huán)。
對(duì)于while循環(huán),它其實(shí)是一個(gè)加強(qiáng)的if語(yǔ)句,如果它的條件為真,那么它就一直執(zhí)行while循環(huán)中的語(yǔ)句中的內(nèi)容。
7.1 For sample
#!/bin/bash
for i in $( ls ; do
echo item: $i
done
在第二行上,我們聲明了一個(gè)i的變量,它將一直將ls命令的結(jié)果全部循環(huán)出來(lái)。其中do 和done之間是所要執(zhí)行的代碼。
While循環(huán)例子
#!/bin/bash
COUNTER=0
while [ $COUNTER -lt 10 ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+1
done
這里面大家可能看到一個(gè)-lt的命令選項(xiàng),這里它代表小于等于
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
Until的例子
#!/bin/bash
COUNTER=20
until [ $COUNTER -lt 10 ]; do
echo COUNTER $COUNTER
let COUNTER-=1
done
函數(shù)
對(duì)于大多數(shù)編程語(yǔ)言,你都可以調(diào)用函數(shù)來(lái)執(zhí)行一段代碼,這樣可以使用減少重復(fù)的書(shū)寫(xiě)代碼。
函數(shù)的例子
#!/bin/bash
function quit {
exit
}
function hello {
echo Hello!
}
hello
quit
echo foo
在2-4行包含了一個(gè)quit函數(shù),在5-7行包含了 hello函數(shù),如果你不是很確定這個(gè)腳本是是什么意思,那么我建議試試它。Notice that a functions don't need to be declared in any specific order.
當(dāng)你運(yùn)行這個(gè)腳本時(shí)你的程序?qū)?huì)最先調(diào)用hello函數(shù),以后再調(diào)用quit函數(shù)最后才執(zhí)行echo 輸出命令。
在函數(shù)中使用參數(shù)
#!/bin/bash
function quit {
exit
}
function e {
echo $1
}
e Hello
e World
quit
echo foo
這個(gè)腳本幾乎和前一個(gè)腳本沒(méi)有什么不能,但最主要的不同是e這個(gè)函數(shù)可以使用參數(shù)了。
用戶接口
使用select命令制作簡(jiǎn)單的菜單
#!/bin/bash
OPTIONS="Hello Quit"
select opt in $OPTIONS; do
if [ "$opt" = "Quit" ]; then
echo done
exit
elif [ "$opt" = "Hello" ]; then
echo Hello World
else
clear
echo bad option
fi
done
如果你運(yùn)行這個(gè)腳本你將會(huì)看到一個(gè)非常簡(jiǎn)單的菜單
使用read讀入用戶輸入
在多數(shù)情況下你可能會(huì)用到提示請(qǐng)進(jìn)行輸入這種狀態(tài)并且有幾種方法可以用。這是其中的一種方法:
#!/bin/bash
echo Please, enter your name
read NAME
echo "Hi $NAME!"
對(duì)于變量來(lái)說(shuō),你可以通過(guò)多個(gè)值來(lái)讀入。
#!/bin/bash
echo Please, enter your firstname and lastname
read FN LN
echo "Hi! $LN, $FN !"
算術(shù)操作
使用以下的命令:
echo 1 + 1
如果你希望看到2,那么你會(huì)很失望,那么我們應(yīng)該如何進(jìn)行操作哪? echo $((1+1))
我們可以使用以下方法:
echo $[1+1]
算術(shù)操作
+
-
*
/
% (remainder)
關(guān)系操作
-lt (<
-gt (>
-le (<=)
-ge (>=)
-eq (==)
-ne (!=)
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -