Shell:函式、輸入輸出重定向、檔案包含
函式
使用者可以定義函式,然後在Shell指令碼中進行呼叫。
shell中函式的定義格式如下:
funcname() {
action;
[return int;]
}
其中:
1. 可以帶function fun() 定義,也可以直接fun() 定義,不帶任何引數。
2. 引數返回,可以顯示地加return 返回,後跟數值n(0-255)。如果不加return,將以最後一條命令的執行結果作為返回值。
下面的例子定義了一個函式並進行呼叫:
demoFun() {
echo "這是我的第一個 shell 函式!"
}
echo "-----函式開始執行-----"
demoFun
echo "-----函式執行完畢-----"
輸出結果:
-----函式開始執行-----
這是我的第一個 shell 函式!
-----函式執行完畢-----
下面定義一個帶有return語句的函式:
funWithReturn(){
echo "這個函式會對輸入的兩個數字進行相加運算..."
echo "輸入第一個數字: "
read aNum
echo "輸入第二個數字: "
read anotherNum
echo "兩個數字分別為 $aNum 和 $anotherNum !"
return $(($aNum +$anotherNum))
}
funWithReturn
echo "輸入的兩個數字之和為 $? !"
輸出類似下面:
這個函式會對輸入的兩個數字進行相加運算...
輸入第一個數字:
1
輸入第二個數字:
2
兩個數字分別為 1 和 2 !
輸入的兩個數字之和為 3 !
函式返回值在呼叫該函式後通過 $?
來獲得。
函式的引數
在Shell中,呼叫函式時可以向其傳遞引數。在函式體內部,通過
帶引數的函式示例:
funWithParam(){
echo "第一個引數為 $1 !"
echo "第二個引數為 $2 !"
echo "第十個引數為 $10 !"
echo "第十個引數為 ${10} !"
echo "第十一個引數為 ${11} !"
echo "引數總數有 $# 個!"
echo "作為一個字串輸出所有引數 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
輸出結果:
第一個引數為 1 !
第二個引數為 2 !
第十個引數為 10 !
第十個引數為 34 !
第十一個引數為 73 !
引數總數有 11 個!
作為一個字串輸出所有引數 1 2 3 4 5 6 7 8 9 34 73 !
注意:
$10
不能獲取第十個引數,而是要用${10}
。當n>=10
時,需要使用${n}
來獲取引數。
另外,還有幾個特殊字元用來處理引數:
$# 傳遞到指令碼的引數個數
$* 以一個單字串顯示所有向指令碼傳遞的引數
$$ 指令碼執行的當前程序ID號
$! 後臺執行的最後一個程序的ID號
[email protected] 與$*相同,但是使用時加引號,並在引號中返回每個引數。
$- 顯示Shell使用的當前選項,與set命令功能相同。
$? 顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。
輸入輸出
預設情況下,Linux系統從終端接受輸入並將所產生的輸出傳送回終端。
輸入輸出的重定向命令列表如下:
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 之間的內容作為輸入。
需要注意的是:
檔案描述符 0 通常是標準輸入(STDIN),1 是標準輸出(STDOUT),2 是標準錯誤輸出(STDERR)。
輸出重定向
重定向一般通過在命令間插入特定的符號來實現。特別的,這些符號的語法如下所示:
command1 > file1
上面這個命令執行command1然後將輸出的內容存入file1。
注意檔案file1內已存在的內容將被新內容替代。如果要將新內容新增在檔案末尾,請使用>>
操作符。
例項
執行下面的 who 命令,它將命令的完整輸出結果重定向到使用者檔案(users)中:
who > users
指令碼執行後不會在終端輸出資訊,這是因為輸出已經從預設的終端重定向到指定的檔案users了。
你可以使用 cat 命令檢視檔案內容:
cat users
_mbsetupuser console Oct 31 17:35
tianqixin console Oct 31 17:35
tianqixin ttys000 Dec 1 11:33
輸出重定向會覆蓋檔案內容,請看下面的例子:
echo "菜鳥教程:www.runoob.com" > users
cat users
菜鳥教程:www.runoob.com
如果不希望檔案內容被覆蓋,可以使用 >>
追加到檔案末尾,例如:
echo "菜鳥教程:www.runoob.com" >> users
cat users
菜鳥教程:www.runoob.com
菜鳥教程:www.runoob.com
輸入重定向
和輸出重定向一樣,也可以從檔案獲取輸入,語法為:
command1 < file1
這樣,本來需要從鍵盤獲取輸入的命令會轉移到檔案讀取內容。
例項
統計 users 檔案的行數,一般寫法:
wc -l users
#輸出:
2 users
也可以將輸入重定向到 users 檔案:
wc -l < users
#輸出:
2
注意:
上面兩個例子的結果不同:第一個例子,會輸出檔名,第二個不會,因為它僅僅知道從標準輸入讀取內容。
重定向深入講解
一般情況下,每個 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
如果希望將 stdout 和 stderr 合併後重定向到 file,可以這樣寫:
command > file 2>&1
或者
command >> file 2>&1
如果希望對 stdin 和 stdout 都重定向,可以這樣寫:
command < file1 >file2
command 命令將 stdin 重定向到 file1,將 stdout 重定向到 file2。
Here Document
Here Document 是 Shell 中的一種特殊的重定向方式,用來將輸入重定向到一個互動式 Shell 指令碼或程式。
它的基本的形式如下:
command << delimiter
document
delimiter
它的作用是將兩個 delimiter 之間的內容(document) 作為輸入傳遞給 command。
注意:
結尾的delimiter 一定要頂格寫,前面不能有任何字元,後面也不能有任何字元。
例項
在命令列中通過 wc -l
命令計算 Here Document 的行數:
wc -l << EOF
歡迎來到
菜鳥教程
www.runoob.com
EOF
3 # 輸出結果為 3 行
我們也可以將 Here Document 用在指令碼中,例如:
cat << EOF
歡迎來到
菜鳥教程
www.runoob.com
EOF
執行以上指令碼,輸出結果:
歡迎來到
菜鳥教程
www.runoob.com
/dev/null 檔案
如果希望執行某個命令,但又不希望在螢幕上顯示輸出結果,那麼可以將輸出重定向到 /dev/null
:
command > /dev/null
/dev/null 是一個特殊的檔案,寫入到它的內容都會被丟棄.如果嘗試從該檔案讀取內容,那麼什麼也讀不到。但是 /dev/null
檔案非常有用,將命令的輸出重定向到它,會起到禁止輸出的效果。
如果希望遮蔽 stdout 和 stderr,可以這樣寫:
command > /dev/null 2>&1
檔案包含
和其他語言一樣,Shell 也可以包含外部指令碼。這樣可以很方便地封裝一些公用程式碼作為一個獨立的檔案。
Shell 檔案包含的語法格式如下:
. filename # 注意點號(.)和檔名中間有一空格
#或
source filename
例項
建立兩個 shell 指令碼檔案。
test1.sh 程式碼如下:
url="http://www.runoob.com"
test2.sh 程式碼如下:
#使用 . 號來引用test1.sh 檔案
. ./test1.sh
#或者
# source ./test1.sh
echo "菜鳥教程官網地址:$url"
接下來,執行test2.sh,結果為:
菜鳥教程官網地址:http://www.runoob.com