1. 程式人生 > >Shell:函式、輸入輸出重定向、檔案包含

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
兩個數字分別為 12 !
輸入的兩個數字之和為 3 !

函式返回值在呼叫該函式後通過 $? 來獲得。

函式的引數

在Shell中,呼叫函式時可以向其傳遞引數。在函式體內部,通過 n1表示第一個引數,$2表示第二個引數…
帶引數的函式示例:

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