相信每一個人對於操作系統的重定向不會陌生了。就是>, >>, <, <<,關於重定向的基本知識我就不說了。這裡主要討論bash的重定向中的一個鮮為人知的東西,那就是bash腳本的函數也可以定義相關的重定向操作。這可不是命令級的重定向,這是函數級的重點向。這並不是一個新的東西,我只是想告訴大家一個已經存在了多年但卻可能不被人常用的功能。
關於bash的這個函數級的重定向的語法其實很簡單,你只需要在函數結尾時加上一些重定向的定義或指示符就可以了。下面是一個示例:
function mytest() { ... } < mytest.in > mytest.out 2> mytest.err
現在,只要是test被調用,那麼,這個函數就會從mytest.in讀入數據,並把輸出重定向到mytest.out文件中,然後標准錯誤則輸出到mytest.err文件中。是不是很簡單?
因為函數級的重定向僅當在被函數調用的時候才會起作用,而且其也是腳本的一部分,所以,你自然也可以使用變量來借文件名。下面是一個示例:
#!/bin/bash function mytest() { echo Hello World CoolShell.cn } >$out out=mytest1.out mytest out=mytest2.out mytest
這樣一來,標准輸出的重定向就可以隨$out變量的改變而改變了。在上面的例子中,第一個調是重定向到mytest1.out,第二個則是到mytest2.out。
$ bash mytest.sh; more mytest?.out :::::::::::::: mytest1.out :::::::::::::: Hello World CoolShell.cn :::::::::::::: mytest2.out :::::::::::::: Hello World CoolShell.cn
正如前面所說的一樣,這裡並沒有什麼新的東西。上面的這個示例,轉成傳統的寫法是:
#!/bin/bash function mytest() { echo Hello World CoolShell.cn } mytest >mytest1.out mytest >mytest2.out
到此為此,好像這個feature並沒有什麼特別的實用之處。有一個可能比較實用的用法可能是把把你所有代碼的的標准錯誤重定向到一個文件中去。如下面所示:
#!/bin/bash log=err.log function error() { echo "$*" >&2 } function mytest1() { error mytest1 hello1 world1 coolshell.cn } function mytest2() { error mytest2 hello2 world2 coolshell.cn } function main() { mytest1 mytest2 } 2>$log main
運行上面的腳本,你可以得到下面的結果:
$ bash mytest.sh ;cat err.log mytest1 hello1 world1 coolshell.cn mytest2 hello2 world2 coolshell.cn
當然,你也可以不用定義一個函數,只要是{…} 語句塊,就可以使用函數級的重定向,就如下面的示例一樣:
#!/bin/bash log=err.log function error() { echo "$*" >&2 } function mytest1() { error mytest1 hello1 world1 coolshell.cn } function mytest2() { error mytest2 hello2 world2 coolshell.cn } { mytest1 mytest2 } 2>$log
你也可以重定向 (…) 語句塊,但那會導致語句被執行於一個sub-shell中,這可能會導致一些你不期望的行為或問題,因為sub-shell是在另一個進程中。
如果你問,我們是否可以覆蓋函數級的重定向。答案是否定的。如果你試圖這樣做,那麼,函數調用點的重定向會首先執行,然後函數定義上的重定向會將其覆蓋。下面是一個示例:
#!/bin/bash function mytest() { echo hello world coolshell.cn } >out1.txt mytest >out2.txt
運行結果是,out2.txt會被建立,但裡面什麼也沒有。
下面是一個重定向標准輸入的例子:
#!/bin/bash function mytest() { while read line do echo $line done } <<EOF hello coolshell.cn EOF mytest
下面是其運行結果:
$ bash mytest.sh hello coolshell.cn
(全文完)