一、 Shell簡介:什麼是Shell,Shell命令的兩種執行方式1php
二、 幾種常見的Shell1html
6、Shell變量:Shell變量的定義、刪除變量、只讀變量、變量類型5bash
7、Shell特殊變量:Shell $0, $#, $*, $@, $?, $$和命令行參數6編程語言
八、 Shell替換:Shell變量替換,命令替換,轉義字符9編輯器
九、 Shell運算符:Shell算數運算符、關係運算符、布爾運算符、字符串運算符12ide
二11、Shell函數:Shell函數返回值、刪除函數、在終端調用函數35
二十3、Shell輸入輸出重定向:Shell Here Document,/dev/null文件38
與其餘編程語言相似,Shell支持for循環。
for循環通常格式爲:
for 變量 in 列表do command1 command2 ... commandNdone
列表是一組值(數字、字符串等)組成的序列,每一個值經過空格分隔。每循環一次,就將列表中的下一個值賦給變量。
in 列表是可選的,若是不用它,for 循環使用命令行的位置參數。
例如,順序輸出當前列表中的數字:
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
運行結果:
The value is: 1The value is: 2The value is: 3The value is: 4The value is: 5
順序輸出字符串中的字符:
for str in 'This is a string'
do
echo $str
done
運行結果:
This is a string
顯示主目錄下以 .bash 開頭的文件:
#!/bin/bash
for FILE in $HOME/.bash*
do
echo $FILE
done
運行結果:
/root/.bash_history/root/.bash_logout/root/.bash_profile/root/.bashrc
while循環用於不斷執行一系列命令,也用於從輸入文件中讀取數據;命令一般爲測試條件。其格式爲:
while commanddo Statement(s) to be executed if command is truedone
命令執行完畢,控制返回循環頂部,從頭開始直至測試條件爲假。
如下是一個基本的while循環,測試條件是:若是COUNTER小於5,那麼返回 true。COUNTER從0開始,每次循環處理時,COUNTER加1。運行上述腳本,返回數字1到5,而後終止。
COUNTER=0
while [ $COUNTER -lt 5 ]
do
COUNTER='expr $COUNTER+1'
echo $COUNTER
done
運行腳本,輸出:
12345
while循環可用於讀取鍵盤信息。下面的例子中,輸入信息被設置爲變量FILM,按<Ctrl-D>結束循環。
echo 'type <CTRL-D> to terminate'
echo -n 'enter your most liked film: '
while read FILM
do
echo "Yeah! great film the $FILM"
done
運行腳本,輸出相似下面:
type <CTRL-D> to terminateenter your most liked film: Sound of MusicYeah! great film the Sound of Music
until 循環執行一系列命令直至條件爲 true 時中止。until 循環與 while 循環在處理方式上恰好相反。通常while循環優於until循環,但在某些時候,也只是極少數狀況下,until 循環更加有用。
until 循環格式爲:
until commanddo Statement(s) to be executed until command is truedone
command 通常爲條件表達式,若是返回值爲 false,則繼續執行循環體內的語句,不然跳出循環。
例如,使用 until 命令輸出 0 ~ 9 的數字:
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
運行結果:
0123456789
在循環過程當中,有時候須要在未達到循環結束條件時強制跳出循環,像大多數編程語言同樣,Shell也使用 break 和 continue 來跳出循環。
break命令
break命令容許跳出全部循環(終止執行後面的全部循環)。
下面的例子中,腳本進入死循環直至用戶輸入數字大於5。要跳出這個循環,返回到shell提示符下,就要使用break命令。
#!/bin/bash
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5, game is over!"
break
;;
esac
done
在嵌套循環中,break 命令後面還能夠跟一個整數,表示跳出第幾層循環。例如:
break n
表示跳出第 n 層循環。
下面是一個嵌套循環的例子,若是 var1 等於 2,而且 var2 等於 0,就跳出循環:
#!/bin/bash
for var1 in 1 2 3
do
for var2 in 0 5
do
if [ $var1 -eq 2 -a $var2 -eq 0 ]
then
break 2
else
echo "$var1 $var2"
fi
done
done
如上,break 2 表示直接跳出外層循環。運行結果:
1 01 5
continue命令
continue命令與break命令相似,只有一點差異,它不會跳出全部循環,僅僅跳出當前循環。
對上面的例子進行修改:
#!/bin/bash
while :
do
echo -n "Input a number between 1 to 5: "
read aNum
case $aNum in
1|2|3|4|5) echo "Your number is $aNum!"
;;
*) echo "You do not select a number between 1 to 5!"
continue
echo "Game is over!"
;;
esac
done
運行代碼發現,當輸入大於5的數字時,該例中的循環不會結束,語句
echo "Game is over!"
永遠不會被執行。
一樣,continue 後面也能夠跟一個數字,表示跳出第幾層循環。
再看一個 continue 的例子:
#!/bin/bash
NUMS="1 2 3 4 5 6 7"
for NUM in $NUMS
do
Q=`expr $NUM % 2`
if [ $Q -eq 0 ]
then
echo "Number is an even number!!"
continue
fi
echo "Found odd number"
done
運行結果:
Found odd numberNumber is an even number!!Found odd numberNumber is an even number!!Found odd numberNumber is an even number!!Found odd number
二11、Shell函數:Shell函數返回值、刪除函數、在終端調用函數
函數可讓咱們將一個複雜功能劃分紅若干模塊,讓程序結構更加清晰,代碼重複利用率更高。像其餘編程語言同樣,Shell 也支持函數。Shell 函數必須先定義後使用。
Shell 函數的定義格式以下:
function_name () { list of commands [ return value ]}
若是你願意,也能夠在函數名前加上關鍵字 function:
function function_name () { list of commands [ return value ]}
函數返回值,能夠顯式增長return語句;若是不加,會將最後一條命令運行結果做爲返回值。
Shell 函數返回值只能是整數,通常用來表示函數執行成功與否,0表示成功,其餘值表示失敗。若是 return 其餘數據,好比一個字符串,每每會獲得錯誤提示:「numeric argument required」。
若是必定要讓函數返回字符串,那麼能夠先定義一個變量,用來接收函數的計算結果,腳本在須要的時候訪問這個變量來得到函數返回值。
先來看一個例子:
#!/bin/bash
# Define your function here
Hello () {
echo "Url is http://see.xidian.edu.cn/cpp/shell/"
}
# Invoke your function
Hello
運行結果:
$./test.shHello World$
調用函數只須要給出函數名,不須要加括號。
再來看一個帶有return語句的函數:
#!/bin/bash
funWithReturn(){
echo "The function is to get the sum of two numbers..."
echo -n "Input first number: "
read aNum
echo -n "Input another number: "
read anotherNum
echo "The two numbers are $aNum and $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
# Capture value returnd by last command
ret=$?
echo "The sum of two numbers is $ret !"
運行結果:
The function is to get the sum of two numbers...Input first number: 25Input another number: 50The two numbers are 25 and 50 !The sum of two numbers is 75 !
函數返回值在調用該函數後經過 $? 來得到。
再來看一個函數嵌套的例子:
#!/bin/bash
# Calling one function from another
number_one () {
echo "Url_1 is http://see.xidian.edu.cn/cpp/shell/"
number_two
}
number_two () {
echo "Url_2 is http://see.xidian.edu.cn/cpp/u/xitong/"
}
number_one
運行結果:
Url_1 is http://see.xidian.edu.cn/cpp/shell/Url_2 is http://see.xidian.edu.cn/cpp/u/xitong/
像刪除變量同樣,刪除函數也可使用 unset 命令,不過要加上 .f 選項,以下所示:
$unset .f function_name
若是你但願直接從終端調用函數,能夠將函數定義在主目錄下的 .profile 文件,這樣每次登陸後,在命令提示符後面輸入函數名字就能夠當即調用。
在Shell中,調用函數時能夠向其傳遞參數。在函數體內部,經過 $n 的形式來獲取參數的值,例如,$1表示第一個參數,$2表示第二個參數...
帶參數的函數示例:
#!/bin/bash
funWithParam(){
echo "The value of the first parameter is $1 !"
echo "The value of the second parameter is $2 !"
echo "The value of the tenth parameter is $10 !"
echo "The value of the tenth parameter is ${10} !"
echo "The value of the eleventh parameter is ${11} !"
echo "The amount of the parameters is $# !" # 參數個數
echo "The string of the parameters is $* !" # 傳遞給函數的全部參數
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
運行腳本:
The value of the first parameter is 1 !The value of the second parameter is 2 !The value of the tenth parameter is 10 !The value of the tenth parameter is 34 !The value of the eleventh parameter is 73 !The amount of the parameters is 12 !The string of the parameters is 1 2 3 4 5 6 7 8 9 34 73 !"
注意:$10 不能獲取第十個參數,獲取第十個參數須要${10}。當n>=10時,須要使用${n}來獲取參數。
另外,還有幾個特殊變量用來處理參數,前面已經提到:
特殊變量 |
說明 |
$# |
傳遞給函數的參數個數。 |
$* |
顯示全部傳遞給函數的參數。 |
$@ |
與$*相同,可是略有區別,請查看Shell特殊變量。 |
$? |
函數的返回值。 |
二十3、Shell輸入輸出重定向:Shell Here Document,/dev/null文件
Unix 命令默認從標準輸入設備(stdin)獲取輸入,將結果輸出到標準輸出設備(stdout)顯示。通常狀況下,標準輸入設備就是鍵盤,標準輸出設備就是終端,即顯示器。
輸出重定向
命令的輸出不只能夠是顯示器,還能夠很容易的轉移向到文件,這被稱爲輸出重定向。
命令輸出重定向的語法爲:
$ command > file
這樣,輸出到顯示器的內容就能夠被重定向到文件。
例如,下面的命令在顯示器上不會看到任何輸出:
$ who > users
打開 users 文件,能夠看到下面的內容:
$ cat usersoko tty01 Sep 12 07:30ai tty15 Sep 12 13:32ruth tty21 Sep 12 10:10pat tty24 Sep 12 13:07steve tty25 Sep 12 13:03$
輸出重定向會覆蓋文件內容,請看下面的例子:
$ echo line 1 > users$ cat usersline 1ss$
若是不但願文件內容被覆蓋,可使用 >> 追加到文件末尾,例如:
$ echo line 2 >> users$ cat usersline 1line 2$
輸入重定向
和輸出重定向同樣,Unix 命令也能夠從文件獲取輸入,語法爲:
command < file
這樣,原本須要從鍵盤獲取輸入的命令會轉移到文件讀取內容。
注意:輸出重定向是大於號(>),輸入重定向是小於號(<)。
例如,計算 users 文件中的行數,可使用下面的命令:
$ wc -l users2 users$
也能夠將輸入重定向到 users 文件:
$ wc -l < users2$
注意:上面兩個例子的結果不一樣:第一個例子,會輸出文件名;第二個不會,由於它僅僅知道從標準輸入讀取內容。
重定向深刻講解
通常狀況下,每一個 Unix/Linux 命令運行時都會打開三個文件:
標準輸入文件(stdin):stdin的文件描述符爲0,Unix程序默認從stdin讀取數據。
標準輸出文件(stdout):stdout 的文件描述符爲1,Unix程序默認向stdout輸出數據。
標準錯誤文件(stderr):stderr的文件描述符爲2,Unix程序會向stderr流中寫入錯誤信息。
默認狀況下,command > file 將 stdout 重定向到 file,command < file 將stdin 重定向到 file。
若是但願 stderr 重定向到 file,能夠這樣寫:
$command 2 > file
若是但願 stderr 追加到 file 文件末尾,能夠這樣寫:
$command 2 >> file
2 表示標準錯誤文件(stderr)。
若是但願將 stdout 和 stderr 合併後重定向到 file,能夠這樣寫:
$command > file 2>&1
或
$command >> file 2>&1
若是但願對 stdin 和 stdout 都重定向,能夠這樣寫:
$command < file1 >file2
command 命令將 stdin 重定向到 file1,將 stdout 重定向到 file2。
所有可用的重定向命令列表 |
|
命令 |
說明 |
command > file |
將輸出重定向到 file。 |
command < file |
將輸入重定向到 file。 |
command >> file |
將輸出以追加的方式重定向到 file。 |
n > file |
將文件描述符爲 n 的文件重定向到 file。 |
n >> file |
將文件描述符爲 n 的文件以追加的方式重定向到 file。 |
n >& m |
將輸出文件 m 和 n 合併。 |
n <& m |
將輸入文件 m 和 n 合併。 |
<< tag |
將開始標記 tag 和結束標記 tag 之間的內容做爲輸入。 |
Here Document
Here Document 目前沒有統一的翻譯,這裏暫譯爲」嵌入文檔「。Here Document 是 Shell 中的一種特殊的重定向方式,它的基本的形式以下:
command << delimiter
document
delimiter
它的做用是將兩個 delimiter 之間的內容(document) 做爲輸入傳遞給 command。
注意:
結尾的delimiter 必定要頂格寫,前面不能有任何字符,後面也不能有任何字符,包括空格和 tab 縮進。
開始的delimiter先後的空格會被忽略掉。
下面的例子,經過 wc -l 命令計算 document 的行數:
$wc -l << EOF This is a simple lookup program for good (and bad) restaurants in Cape Town.EOF3$
也能夠 將 Here Document 用在腳本中,例如:
#!/bin/bash
cat << EOF
This is a simple lookup program
for good (and bad) restaurants
in Cape Town.
EOF
運行結果:
This is a simple lookup programfor good (and bad) restaurantsin Cape Town.
下面的腳本經過 vi 編輯器將 document 保存到 test.txt 文件:
#!/bin/sh
1.
filename=test.txt
vi $filename <<EndOfCommands
i
This file was created automatically from
a shell script
^[
ZZ
EndOfCommands
運行腳本:
$ sh test.shVim: Warning: Input is not from a terminal$
打開 test.txt,能夠看到下面的內容:
$ cat test.txtThis file was created automatically froma shell script$
/dev/null 文件
若是但願執行某個命令,但又不但願在屏幕上顯示輸出結果,那麼能夠將輸出重定向到 /dev/null:
$ command > /dev/null
/dev/null 是一個特殊的文件,寫入到它的內容都會被丟棄;若是嘗試從該文件讀取內容,那麼什麼也讀不到。可是 /dev/null 文件很是有用,將命令的輸出重定向到它,會起到」禁止輸出「的效果。
若是但願屏蔽 stdout 和 stderr,能夠這樣寫:
$ command > /dev/null 2>&1
像其餘語言同樣,Shell 也能夠包含外部腳本,將外部腳本的內容合併到當前腳本。
Shell 中包含腳本可使用:
. filename
或
source filename
兩種方式的效果相同,簡單起見,通常使用點號(.),可是注意點號(.)和文件名中間有一空格。
例如,建立兩個腳本,一個是被調用腳本 subscript.sh,內容以下:
url="http://see.xidian.edu.cn/cpp/view/2738.html"
一個是主文件 main.sh,內容以下:
#!/bin/bash
. ./subscript.sh
echo $url
執行腳本:
$chomd +x main.sh./main.shhttp://see.xidian.edu.cn/cpp/view/2738.html$
注意:被包含腳本不須要有執行權限。