看板 Linux 關於我們 聯絡資訊
我想將stderr的訊息額外導到檔案, 也就是說error訊息除了輸出到螢幕之外 ,還要輸出到檔案。 如果是stdout的話,可以使用tee來達成, 但stderr要怎麼做呢? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.121.236.62
legnaleurc:2>tee 10/28 07:23
legnaleurc:啊, 好像不太對 ... 10/28 07:23
bitlife:如果可以接受stderr和stdout同一檔案,那就是 2>&1 再 | 10/28 07:41
bitlife:myprogram 2>&1 | tee output-file 10/28 07:42
bitlife:如果不行,那就要效法上次網友貼的 gdb 大法 10/28 07:42
bitlife:上一行的不行,是指不能接受 out err 同一檔案 10/28 07:43
bitlife:剛才想到,不用 gdb 也可以做 10/28 07:47
bitlife:myprogram 2>output-file ; tail -f output-file 10/28 07:48
kdjf:f(){ echo 1>&3; ls abc 2>&1; }; f 3>&2 把stdin/err對調 10/28 09:25
kdjf:ls exist nonexist 3>&1 1>&2 2>&3 同上,接下來可用tee 10/28 09:46
tsaiminghan:b大的方法不合我用,順序應該會不對 10/28 23:47
tsaiminghan:k大的方法,我要試試能不能用 10/28 23:47
bitlife:所謂順序不對是什麼意思? 10/29 00:03
bitlife:我猜是tail會漏掉一些快速印出的較早內容.那就改一下 10/29 00:04
bitlife:last的參數,讓它能印出所有一開始內容就好 10/29 00:06
bitlife:打錯, 是 tail 的參數 10/29 00:09
myprogram 2>output-file ; tail -f output-file 因為我要導出make的stderr訊息 但是除了錯誤訊息會到stderr,警告訊息也會, 且只有error時,才會停止,警告不會。 所以上面的方法不能用。 ※ 編輯: tsaiminghan 來自: 59.121.233.249 (10/29 02:21)
bitlife:你的意思是如果只有警告,tail 不會結束,而你希望make完都 10/29 08:31
bitlife:一律停止? 10/29 08:31
不是。因為編譯android時,一定會產生警告 我目的如下 我寫了一個編譯android的script 在make時,如果發生error,我會將error訊息存入 檔案,然後寄出來,但是目前發現光只有error很難 debug, 所以想除了stderr之後,也存一份完整的log (包括stdout , stderr),目前就是卡在這裡。 因為編譯android時,會有很多warning訊息,所以 stderr的輸出內容有兩種訊息,照上面的作法是將 stderr的訊息最後接在完整log的後面,這樣log的 順序應該會不正確,因為warning的訊息可能是很早 就產出的。 <=說明不是很詳細,如果看不懂的話,我在寫更詳細。
bitlife:警告是從stdout出來還是stderr? 如果是前者那簡單,如果是 10/29 13:59
bitlife:從stderr(跟error訊息一起)出來,那就變成需要一個軟體 10/29 14:00
bitlife:filter. 把 error 分離出來. 10/29 14:00
bitlife:我懂了,看到你第一次編輯回言,警告也是從stderr出來. 10/29 14:01
bitlife:那只有寫個軟體filter了. 10/29 14:01
tsaiminghan:沒寫過filter,暫時不打算這麼做,先看看k大的方法行 10/29 14:55
tsaiminghan:不行 10/29 14:55
bitlife:k大的方法一樣是在OS層面處理,你的問題是Ap應用層面(把 10/29 16:07
bitlife:所需的error訊息特別過濾出來),應該是一樣不行. 10/29 16:07
bitlife:filter也沒什麼特別, a | b | c 的 b 就叫 filter 10/29 16:08
bitlife:你把error/warning的文字範例提供一下,說不定馬上有人可以 10/29 16:08
bitlife:用 grep/sed/awk 等工具立刻組一個給你 10/29 16:09
原來filter是這個意思。 另外make執行時,發生的錯誤訊息應該不是很固定吧? 所以filter應該不好寫。 且本來stderr和stdout輸出就是分開的,現在把它合起來,然後另外寫個 filter來把特定字串找出來,我覺得真是作白工XD k大的方法說可以把stdout/err對調,如果真的可以的話,配合tee,應該可以 達成我的需求。 ※ 編輯: tsaiminghan 來自: 59.121.130.222 (10/29 16:52)
bitlife:可是你前面不是說警告也走 stderr 出來?還是我誤解了? 10/29 16:55
是啊, 警告也是從stderr出來,但是因為發生error時,error訊息會在stderr最後面, 所以輸出的檔案我只要看最後面就可以抓到錯誤訊息。 但是因為光錯誤訊息,沒有stdout輸出,不容易知道發生什麼事,所以才希望有完整 的log,然後由error訊息去完整log中找到發生問題的點,看發生什麼事。 ※ 編輯: tsaiminghan 來自: 59.121.130.222 (10/29 17:02)
bitlife:還是搞了半天,你只想把stdout, stderr 的內容照時間順序合 10/29 16:58
bitlife:併顯示並且log? 如果真的是這樣,那解法不用這麼複雜. 10/29 16:59
bitlife:就用傳統的 2>&1 把 stdout dup 給 stderr 就好. 10/29 17:00
bitlife:myprogram 2>&1 | tee output-file 10/29 17:01
tsaiminghan:上面的方法因為要在整個log中找error發生點 10/29 17:03
tsaiminghan:所以才會希望另外產生一個只存stderr訊息的檔案 10/29 17:03
tsaiminghan:這樣可以方便找error的發生點 10/29 17:04
bitlife:那就綜合各方法如下 10/29 17:05
bitlife:rm err-file ; touch err-file 10/29 17:05
bitlife:tail -f err-file & 10/29 17:05
bitlife:myprogram 2>>err-file | tee out-file 10/29 17:05
bitlife:cat out-file err-file > single-out-err-file 10/29 17:06
bitlife:如果你make時螢幕訊息不重要,那更簡單 10/29 17:07
bitlife:myprogram > out-file 2>err-file 10/29 17:07
bitlife:再用上述的 cat 命令合併就好了 10/29 17:07
tsaiminghan:上面的方法是我目前在用的(我只差把檔案合成一個) 10/29 17:10
tsaiminghan:問題是這樣合出來的log,順序不對 10/29 17:11
tsaiminghan:會沒辦法知道發生error時stdout輸出什麼 10/29 17:12
bitlife:要順序對,要用我推文 17:01 的那個方法 10/29 17:13
tsaiminghan:所以我理想中是產生一個正常順序的完整log(包括 10/29 17:14
tsaiminghan:stdout 和stderr),且有額外一份只存stderr的log 10/29 17:14
bitlife:然後假如make時間不會很久,平常先用一般方法產生err-file 10/29 17:15
bitlife:發生錯誤時,立刻再執行一次 17:01那個方法,兩次來比對 10/29 17:15
tsaiminghan:總之我試試看,先謝謝bitlife大力幫忙 10/29 17:16
bitlife:你講的這個需求,如果 make 有支援 log4c (log4j的c版)才有 10/29 17:18
bitlife:希望了. 10/29 17:18
tsaiminghan:我要編譯的是android....編一次大約要50分鐘XD 10/29 17:18
bitlife:不客氣,希望有用就好. 10/29 17:18
tsaiminghan:所以K大的方法,如果真的可以把stdout和err調換 10/29 17:19
bitlife:看來用程式把 error 以 pattern 來 grep/sed/awk 抓出來 10/29 17:19
bitlife:比較有希望. 10/29 17:19
tsaiminghan:配合tee應該可以做到 10/29 17:19
bitlife:把stdout,stderr 的descriptor互換,沒有改變什麼啊? 10/29 17:20
bitlife:現在的問題是只一次 make,你要一次產生單一時序輸出檔,又 10/29 17:21
bitlife:有一個單純只有 stderr 的檔,那是基本上相斥的事. 10/29 17:21
tsaiminghan:tee可以把stdout的資料分流到stdou和檔案 10/29 17:22
我不確定行不行但是 想法如下 如果stdout和stderr換過來 ====script A.sh====== make | tee err.log ================== ====script B.sh==== a.sh &> all.log ※ 編輯: tsaiminghan 來自: 59.121.131.72 (10/29 17:24)
bitlife:事實上,我剛熊熊才想到 17:01 那行根本是脫褲子放X. XD 10/29 17:23
bitlife:一般程式一開始 stdout 和 stderr 都只向終端機. 10/29 17:24
bitlife:tee 只是讓你看畫面兼log至檔案.現在問題是stdout和stderr 10/29 17:24
bitlife:一開始是一體的. 你要分開它們,就不能一起tee 10/29 17:25
bitlife:因為stdout和stderr一開始是都指向tty/pty,所以你掉換還是 10/29 17:26
bitlife:同一個東西,會tee到的內容還是一樣. XD 10/29 17:26
tsaiminghan:了解...那你的意思是tee是抓不到stderr的資訊 10/29 17:28
bitlife:我想了一下. 是有可能... 因為 pipe 只針對 stdin/stdout 10/29 17:28
tsaiminghan:即使我把fd的輸出換過來? 10/29 17:28
bitlife:不過,再想一下,還是怪怪的. 只能等你試看看了. 10/29 17:30
bitlife:整個麻煩就在於你同時需要合流和分流. 調換stdout/stderr 10/29 17:30
bitlife:是會讓 tee 能從它自己的 stdin 取得 make 的 stdout (包 10/29 17:31
bitlife:含error/warning,因為out/err有swap過) 10/29 17:31
tsaiminghan:好啊,星期一時再試試看 10/29 17:31
bitlife:但是因為經過pipe,就分流了,所以我懷疑b.sh就算抓到全部內 10/29 17:32
bitlife:容,時序也會亂掉.更何況我不確定b.sh是否能抓到全部的log 10/29 17:32
bitlife:簡單講,只有(out,err)合流,才會保證有正確的時序 10/29 17:33
bitlife:似乎很難一次做兩個相反目的的工作. 10/29 17:33
bitlife:你要不要貼一下wanring/error範例,用filter搞不好還容易些 10/29 17:34
tsaiminghan:這倒是個問題,就算順序亂掉了,我也不一定能發現 10/29 17:34
bitlife:我17:01的那一行,在(out,err)合流的前提下,又不是脫X放X了 10/29 17:35
tsaiminghan:真弄不出來的話,也只是照現在的清況繼續用而已 10/29 17:36
bitlife:那行確保out,err即使app的fd不同,但用同一個OS的內部fd 10/29 17:36
tsaiminghan:filter就再看看吧,老實說發生error的訊息會長什麼樣 10/29 17:37
bitlife:那麼我建議你用 17:01 那行,確保時序一定正確. 10/29 17:37
tsaiminghan:我現在也不是很確定 10/29 17:37
bitlife:等你測試好了,再回篇新的(舊的這篇可能洗出畫面了),我也有 10/29 17:40
bitlife:興趣知道結果. 10/29 17:40
測試結果不行 輸出互換ok,導出也ok,但 tee的使用跟我想像中不太一樣 以下執行時 xxx | tee zzz.log 會先把stderr印出,然後再印出stdout,因此順序會不對。 所以如果要順序正確,一定要把stdout和stderr導 到同一輸出才行,但導到同一輸出,就做不到分流的目的 ※ 編輯: tsaiminghan 來自: 59.121.128.220 (10/31 23:39)