如果全部都要重定向的話每一條命令后面>>並不方便,可以這么做。
在開頭就聲明
exec 1>>$log_file
表示將腳本中所有的正確輸出全部追加到$log_file,錯誤信息會輸出到stdout。
如果想把錯誤信息也輸出到$log_file,那么只需要補一句
exec 2 >> $log_file
就可以了
利用script命令記錄下會話過程
在Unix系統維護中,有時候系統工程師希望能夠記錄下會話的過程。如在測試一個系統功能的時候,工程師就希望將測試的步驟都一一的紀錄下來。以便出現問 題時利用這份資料進行追蹤分析。如有時候在制作培訓文檔的時候,可能也需要這些會話記錄,以方便培訓師制作PPT等培訓文檔。總之就是一句話,系統工程師 現在想要記錄某個會話的過程,在Unix系統中能否實現? 首先當系統工程師想要記錄某個會話的時候,則只需要在會話開始時輸入script命令。輸入這個命令后,系統就會將當前用戶的所有鍵盤操作、屏幕輸出以及 錯誤信息等等保存到一個特定的文件中。如上面執行了ps命令與who命令后,希望就會將這兩個命令(用戶的鍵盤操作)、屏幕輸出(命令的執行結果)等等保 存到文件中。當工程師需要退出記錄過程時,則只需要輸入exit命令,系統就會就是script done的提示信息。表示系統已經結束了記錄工作。 三、將正確信息與錯誤信息都保存在同一個文件中。
除了可以將正確信息與錯誤信息保存在不同的文件中,還可以將它們合並在同一個文件中。要實現這個需求,可以采取兩種途徑。
一是通過文件合並來實現。即先將錯誤信息與正確信息保存在兩個不同的文件中。然后再需要的時候,來利用文件合並的功能將他們合並在同一個文件中。如利 用cat命令加上>>重定向符號就可以將兩個文件合並在一起了。注意這里用的是>>符號而不是>符號。這個命令很容易理 解,就是先將某個文件中(如保存錯誤信息的文件)的內容讀出來,然后再通過重定向符號>>(這個符號的含義是追加,而不是替換)將讀出來的錯 誤信息追加到另外一個文件中(如保存正確信息的文件)。通過這個方式就可以兩正確信息與錯誤信息合並保存在同一文件中。
1、管道符的" | "的作用只是把前一個程序的標准輸出流(stdout)的數據 作為后一個程序 的標准輸入流stdin的數據,如不進行重定向,則其他輸出流的信息是無法傳給后面的程序的
2、屏幕得到的信息不一定是從程序的標准輸出來的,也包括標准錯誤輸出流stderr中的信息
3、有些程序(特別是象bash 、make這樣執行了其他程序的程序)的設計者為了省事,把一些正常情況的信息也放在stderr中輸出(即使程序本身並無錯誤),而stdout用來輸 出被調用程序的執行時信息,造成了用戶的誤解 簡單編寫了一下腳本,通過ssh登陸在命令行下運行正常,可是將腳本添加到crontab中就不正常。想記錄一下輸出信息,分析一下錯誤原因。 將腳本通過使用 > info.log 重定向輸出,結果發現一些在命令行下可以看到的文本信息沒有記錄到 info.log 文件中,研究了一下,那些輸出估計是輸出到了標准錯誤上。
研究了一下通常添加命令后面幾個輸出含義
■>/dev/null 輸出到空設備,表示丟掉輸出信息。
■2 > &1 將輸出到標准錯誤的信息輸出到標准輸出設備(通常是屏幕) 有3個默認的i/o,
■0 是標准輸入,一般是鍵盤
■1 是標准輸出,一般是屏幕了
■2 是標准錯誤,有時候屏幕上可以看到,但是重定向的文件中看不到的就是它了
在編寫稍微復雜的Shell腳本時,我們常常需要將標准輸出和標准錯誤信息記錄下來,以往我們通過如下形式辦到:
somescript.sh > log 2>&1
但這對規范的shell是不太完美的,一是log文件的位置及名稱,只能由着執行者來定,存在不確定性;二是執行者是否記得使用這樣的句式來確保操作顯示 有記錄,也無法保證
所以,我們需要在shell腳本內部指定,不受執行者影響而記錄下顯示輸出的手段,而且,我們還不能用愚蠢的每句后面來一個| tee $logfile的方式
以下為實現方法,以Korn Shell為准:
變量: logfile - 所有信息輸出的文件
fifofile - 為同時輸出到屏幕和文件所建立的管道文件
Shell內部可以支持的重定向標准輸出和標准錯誤設備的基本方法: exec 1>$logfile exec 2>&1
但是,這樣就只能將所有信息輸出到$logfile,無法實現同時顯示在屏幕的目的。
不可能有exec 1>|tee $logfile的用法
以往,在命令行將錯誤輸出也導向屏幕及文件的方法是: somescript.sh 2>&1 | tee $logfile 這里用到管道,而exec命令並不支持管道用法,所以我們需要建立fifo文件來完成
但是,fifo管道文件是阻塞形管道,沒有隨時將其內容輸出的話,腳本將hang住無法繼續,所以我們要用“cat 管道文件”的方式將其隨時導出,為了不影響后續命令執行,cat這一句必須放到后台。因為cat管道文件內容的時候,永遠不會結束,因為不會遇到EOF標 記(就是控制字符Ctrl-D),除非在管道中出現了Ctrl-D,所以我們在腳本最后需要顯示一個Ctrl-D,比較方便的方法是print "\015"(015是8進制,換算成10進制就是13,即Ctrl-D的ASCII碼) 最后寫法:
test.sh
logfile=test.log
fifofile=test.fifo
mkfifo $fifofile
cat $fifofile | tee $logfile & exec 1>$fifofile exec 2>&1
# some commands to produce normal and error output cal badcommand to generate stderr messages
# print "\015"
復制代碼 運行結果:
[root@system:/tt] sh test.sh October 2008 Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 test.sh[12]: badcommand: not found.
[root@system:/tt] cat test.log October 2008 Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 test.sh[12]: badcommand: not found. [root@system:/tt]
