前言
相信大家都知道bash下time是一個很有用的命令,它可以為一段腳本或一個程式的執行計時,這通常在粗略比較程式執行效率的時候很方便。但你會發現,time指令輸出的時間文字不能被簡單地重定向,例如重定向至一個文字文件,只能顯示在螢幕上,這對於非互動計時很不方便。
例如:
$ time find . -name "mysql.sh" >1.txt real 0m0.081s user 0m0.060s sys 0m0.020s $ time find . -name "mysql.sh" 2>2.txt ./work186/sms/bin/mysql.sh ./work186/sms/src/scripts/mysql.sh ./work186/sms/src/scripts1/mysql.sh ./work186/sms1/bin/mysql.sh ./work186/sms1/src/scripts/mysql.sh ./temp/sms/bin/mysql.sh ./temp/sms/src/scripts/mysql.sh real 0m0.068s user 0m0.040s sys 0m0.030s
透過上面的嘗試,發現無法將time的輸出訊息重新導向到檔案裡面,為什麼?因為time是shell的關鍵字,shell做了特殊處理,它會把time指令後面的指令列當作一個整體來處理,在重定向時,其實是針對後面的指令來的,time指令本身的輸出並不會被重定向的。
關鍵字time設定了一個標記,知道command(find)指令執行完,timing資訊才被印到stderr中。 time關鍵字要整個command和管道,還有相關的重定向都要來得高級。這就是為什麼簡單的重定向對於time而言不起作用。 這是Bash語法定義的。 command之後的重定向對於time而言,是command的一部分。
註:time指令的輸出到標準錯誤(stderr)中
當time指令執行時,command運行於目前shell(也就是time指令所執行的shell)的下一層shell,而time本身的輸出位於目前shell的stderr。像上面所示的重定向只會使得command的stdout被重新導向至一個文字文件,而不會輸出time本身的輸出內容。
第一種解決方法,就是將time指令和將要執行的命令列放到一個shell程式碼區塊中,也就是一對大括號中,要注意空格和分號的使用。
$ { time find . -name "mysql.sh"; } 2>2.txt ./work186/sms/bin/mysql.sh ./work186/sms/src/scripts/mysql.sh ./work186/sms/src/scripts1/mysql.sh ./work186/sms1/bin/mysql.sh ./work186/sms1/src/scripts/mysql.sh ./temp/sms/bin/mysql.sh ./temp/sms/src/scripts/mysql.sh $ cat 2.txt real 0m0.068s user 0m0.030s sys 0m0.040s
第一種方式的嘗試成功了,總結起來就是 { time command-line; } 2>file 注意分隔符的使用。
另一個方式就是使用子Shell的方式
如下圖:
$ (time find . -name "mysql.sh") 2>2.txt ./work186/sms/bin/mysql.sh ./work186/sms/src/scripts/mysql.sh ./work186/sms/src/scripts1/mysql.sh ./work186/sms1/bin/mysql.sh ./work186/sms1/src/scripts/mysql.sh ./temp/sms/bin/mysql.sh ./temp/sms/src/scripts/mysql.sh $ cat 2.txt real 0m0.083s user 0m0.040s sys 0m0.020s [root@web186 root]#
第二種方式的嘗試也成功了,總結起來就是 (time command-line) 2>file 這裡time緊貼著小括號(也可以的,命令列結束也不必帶分號。當然最好還是用第一種方式,畢竟啟動一個子shell是要多佔些資源的。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流。中文網!