知識問題 | [C語言] 請問怎麼攔截pipe前一個程式的stderr? 發問者: (︶︿︶ )_╭∩╮ ( 初學者 5 級) 發問時間: 2009-05-23 18:34:32 解決時間: 2009-06-06 18:49:08 解答贈點: 15 ( 共有 0 人贊助 ) 回答: 2 評論: 0 意見: 20 網友正面評價 100% ( 共有 4 人評價 ) [ 檢舉 ] [C語言] 請問怎麼攔截pipe前一個程式的stderr? 例如 Windows 命令列下, A.exe | B.exe B.exe 要怎麼攔截 A.exe的 STD ERR(標準錯誤輸出) ? 2009-05-23 18:35:14 補充 我用 C scanf 都只能讀到前一個程式的STDOUT. 2009-05-24 23:01:07 補充 回答跟意見都很精采, 我是在make file裡面用的, 最主要是因為 原本make file 內寫 A.exe 2> stderr.log 我想寫成 A.exe | B.exe 然後 B.exe 可以獲得 A.exe的 STDOUT 跟 STDERR 但是實際上只能抓到STDOUT 2009-05-24 23:14:10 補充 Jacob, 感謝您的回答, 這個A | B 2>&1 我自己也試過 這樣 STDERR 會寫到 B.exe檔案上, 破壞了 B.exe檔案內容. 2009-05-24 23:15:24 補充 有空的話請幫忙回答這個問題: 一樣是在make file 內的問題: http://tw.knowledge.yahoo.com/question/question?qid=1509052411383 2009-05-26 00:28:32 補充 Jacob 你的解法可能是對的, 但是我是在make file 內寫的, 還用dos 的 IF 包起來: 例如 (IF .... & \ (X.exe ....) & \ (A.exe .... ) & \ (if ERRORLEVEL 1 .... ) & \ 很奇怪, 這個ERRORLEVEL 若在 (A.exe & echo %ERRORLEVLE% .. )求值 就是0 若是放在 下一列的 (if ERRORLEVEL ...) 求值就是1 2009-05-28 16:17:50 補充 更正拼字: A.exe & echo %ERRORLEVEL% .. ) 2009-06-01 14:54:37 補充 我是把 Windows Command Prompt 語法 寫在 makefile 上, 例如: @if /I "$(AA)" EQU "TRUE" \ 2009-06-01 14:55:33 補充 我知道ERRORLEVEL不是環境變數, 而是上一個程式結束的傳回值. 最佳解答發問者自選 回答者: Jacob Lee ( 大師 4 級 ) 代表知識團: C/C++程式語言討論研究 擅長領域: C&C++ | 作業系統 回答時間: 2009-05-23 21:33:41 [ 檢舉 ] 此題無解! 除非遇到專研 Windows OS-Coding 超超超極秘技的人! StdiErr 通常是定給 螢幕。 而 pipe 只傳 StdOut 給後者的 StdIn 這些動作都是由 OS 執行時設定的。 既然 OS 沒有傳 A 的○○給 B,B 要去撈 OS 裡的東西,包括: 1. 我是被哪東東 pipe 過來的(這東東確定有得撈!但絕對是 OS dependent!) 2. 那東東的 StdErr 在哪? 3. 怎麼改 StdErr(問題是:改了不一定有效!) 而,另一個根本性的問題是: Pipe 的定義是平行執行! MS-DOS 到 6.22 以前,都是假平行; 但,事隔一萬年了,現在的 Windows 應該已經是真平行了! 無論真假,B 不一定能在 A 有 StdErr 前,就改掉 A 的 StdErr 的設定! 尤其是在假平行下,那是絕對無解! 若是真平行,也不能保證! 所以,確定此題無解! = = = = 在程式設計的領域無解,不代表在電腦的領域無解! 你要找的是 OS Command Shell! 有的 Shell 有支援! 不同的 Shell 使用的方法不同,如: 2| 或 &| 不過,這兩招在 XP 的 Shell 確定不能用! = = = = 所以,你不用再到 C 的程式領域找! 找到了你可能也看不懂! 看懂了也不穩定,也有嚴重的 可攜性 的問題! 找 Shell 的玩家比較快! 2009-05-23 21:42:41 補充 若你沒要同時執行的效果,XP 倒是可以作弊! 我弄一下,再補給你。 2009-05-23 22:02:43 補充 A > t.txt 2>&1 B < t.txt del t.txt 這樣就可以了 2009-05-23 22:08:53 補充 剛發現一個神奇的用法,你試試看! 如果合用,應該比上述法更好 A | B 2>&1 2009-05-24 07:45:25 補充 可以請 DeeR 詳看題目 及 所引用的那篇 再武斷地說: 〝絕對〞有解 嗎? 兩年前?五年前我就在做平行運算了,會不知道 sryang 說的那個方法? (當然,它們只是相關: 平行運算不限用在那方法; 那方法不限用在平行運算。 ) 2009-05-25 06:31:54 補充 = = = = 不好意思,是我的錯! 我打錯東西! 不過,我根據我打錯的, 沒把 B 給毀了耶! 只是沒達到效果! 希望沒造成你的災難! 你是不是打成了 A.exe > B.exe 2>&1 我說錯的是 A.exe | B.exe 2>&1 或 A | B 2>&1 = = = = 正確的應該是: A 2>&1 | B 你試試看,應該 不會把 B 給毀了 能正確地把 A 的 StdOut 及 StdErr 都傳給 B 的 Stdin 2009-05-26 12:58:17 補充 ErrorLevel 不是環境變數! 版大的 (A.exe & echo %ERRORLEVLE% .. ) 會是 0 的原因,就是因為 沒有這變數,把它當變數印,當然是 0 而放在 下一列的 (if ERRORLEVEL ...) 求值就是1 因為 意見 017 說的那些東西, 其中有人 的 return code (main function 的 return 值) 是 1 2009-05-26 16:57:59 補充 Makefile 我也玩過好幾年,它的確和 bat 有很大的不同。 至於版大為何會在 makefile 裡用了 pipe 和 & 等,就要問他了。 或許版大是以 bat 的方式,操作類似 makefile 的效果。 把 ErrorLevel 變環境變數的做法,我也寫過數次; 還做過更複雜變化,如:亂數、變成 Menu、用↑↓←→移動光棒等。 = = = = 版大,若你要把ErrorLevel 變成環境變數,要注意你的拼字! 你目前放上來的,字有拼錯。 但,M$ 的 OS 裡,環境變數是沒有 ErrorLevel 的。 (除非最近它又新延伸了。至少,Vesta還沒有) 2009-06-01 15:47:56 補充 大部份的 makefile 有它自己的語法,不是單單吃 OS 的 command shell 的東西。 如果是吃 OS 的 command shell的語法,它會變成 OS dependent 的東西,不太好用! 2009-06-02 11:24:12 補充 鍋子放到瓦斯爐上,能不能拿來烤東西? 可以! 好用嗎? 當然不! 能用嗎? 當然可! 你若有烤箱,為何要用鍋子? 寫程式/操作電腦,也是一樣! 你要好寫介面,有/會 VB, Java,為何要用 C? C 的專長,就不是在做介面! makefile 也一樣! 就算你今天玩出來, 1. 換用下一版的 make、 2. 拿去另一種的 make、 3. 兩年後用同一種同一版的 make 都不一定會成功!( 3. 如樓下講的:你忘了!) 還是不要做這樣的事吧! 把時間花在較普遍、長久、有用的事上。 (請想想,為何一堆東西在講 可攜性/相容性?) 發問者評價: 感謝您的熱心回答, 受益無窮 其他回答(1) 意見(20) 001 回答者: DeeR ( 初學者 3 級 ) 回答時間: 2009-05-24 00:06:22 [ 檢舉 ] 兩年前 就有人問過這類的問題了. http://delphi.ktop.com.tw/board.php?cid=30&fid=69&tid=90571 你可以去看看. sryang 有提供詳細的說明. windows XP 用的. 絕對有解. 2009-05-26 07:56:35 補充 ERRORLEVEL 這個東西, 應該是一個"環境變數", 你用環境變數的方法去試看看吧. 2009-05-26 14:00:00 補充 不是環境變數,就把它變成環境變數囉。 http://www.robvanderwoude.com/errorlevel.php 這邊有教怎麼變。 至於。發問者說要放在 Makefile �堙C確實。它的寫法會跟你用 bat 法不一樣。 make 是否可以像 bat 那樣操作 errorlevel 得要測試看看才知道。 而且。我玩過的3-4種 make 所用的語法, 還是有點差異的。 2009-06-01 19:44:59 補充 問題是......當你的 make 出現 error 時.理當要停下來了呀. 要是再 make 下去.已經是無意義的事了. 如果你是要利用 make 來做 if case..... 的事情. 那是不是應該要變成要分開寫成不同的 target? make 有 make 的目的.它是要讓你做專案管理好管. bat(shell) 有 bat(shell) 的目的. 它們是讓你省掉重覆的動作的. 花太多時間在做這種"超人"的動作. 只是顯得你"好利害"(是不是真利害不知道.) 但是.隔一段時間後.你又忘了當時的寫法, 維護上就會出問題了. 還是用標準動作就好吧. 1 001 意見者: novus ( 專家 5 級 ) 擅長領域: C&C++ | 物理 發表時間: 2009-05-23 23:37:50 [ 檢舉 ] 有相當程度需要靠 case by case 之前有寫過一個可以和gdb互動的 原c++ class在此 http://www.phpbbserver.com/graphicsparalle/viewtopic.php?p=636&mforum=graphicsparalle#636 我的做法是利用windows api 在啟動目的process的時候順便把stdout和stderr綁在一起 002 意見者: novus ( 專家 5 級 ) 擅長領域: C&C++ | 物理 發表時間: 2009-05-23 23:43:15 [ 檢舉 ] 這是需要比較大的互動功能,或是對child process有比較大控制權的時候才需要這麼麻煩 否則應該盡量使用dos本身的pipe重導 003 意見者: Jacob Lee ( 大師 4 級 ) 擅長領域: C&C++ | 作業系統 發表時間: 2009-05-24 07:40:54 [ 檢舉 ] 我認為 回答者 002 DeeR http://tw.knowledge.yahoo.com/my/my?show=AE03201838 誤解了版大的題意。 〝攔截〞 pipe前一個程式的 stderr 也就是說:不是由 A 產生 pipe 給 B 他所引的那篇,用的也是 shell 重新轉向,還比我寫的方法少! 而其中與程式有關的,寫的是『由 A 產生 pipe 給 B』 所以,他說的〝windows XP 用的. 絕對有解.〞, 在版大的文意上,是絕對不錯誤的! = = = = 004 意見者: Jacob Lee ( 大師 4 級 ) 擅長領域: C&C++ | 作業系統 發表時間: 2009-05-24 07:41:24 [ 檢舉 ] (1) 而 Novus 寫的也是『由 A 產生 pipe 給 B』。 (2) 但,他明說:〝否則應該盡量使用dos本身的pipe重導〞 根據 (1),我寫的〝程式領域無解〞仍是正確的! 根據 (2),和我回答的後半:建議版大用 shell 是一致的 另外,shell 既然有提供,何必另尋它法? 再來,要是 無法取得 A 的 source coe, 『由 A 產生 pipe 給 B』就完全行不通! 或是,A已寫得很...,要改由 A 建 Pipe ...會產生一堆 Bug! 所以,仍強烈建議:使用我寫的方法去重導! 不要用『由 A 產生 pipe 給 B』! 005 意見者: Jacob Lee ( 大師 4 級 ) 擅長領域: C&C++ | 作業系統 發表時間: 2009-05-24 07:41:50 [ 檢舉 ] 除非,你要研究的,是 由程式建 pipe (的平行法)。 不然,如 Novus 所言:不建議自己寫 pipe! 也就是說:要不要版大題目寫錯, 『由 A 產生 pipe 給 B』 是完全錯誤的方法: 1. 不合題意 2. 不能解決拿不到 A 的 source 的狀況 3. 要花一些工作時間寫成 4. 方法複雜,但程式改變反而較性少 5. 發展過程會產生一堆 bug! 參考資料:五年以上平行運算研究 007 意見者: Jacob Lee ( 大師 4 級 ) 擅長領域: C&C++ | 作業系統 發表時間: 2009-05-24 08:19:01 [ 檢舉 ] 竟然有重大錯字! 意見 003 最後一句 在版大的文意上,是絕對〝不〞錯誤的! 應該是 在版大的文意上,是絕對〝 〞錯誤的! 意見 005 中間 也就是說:要不〝要〞版大題目寫錯, 應該是 也就是說:要不〝是〞版大題目寫錯 = = = = 根據版大的題意:『B 攔截 A』,不是 A 產生給 B 有什方法可以讓 B 知道 A 的 攔截,本身代表的就是不是〝極〞中規中矩的方法! 也就是說:A 產生 pipe 給 B,就根本不是〝B〞〝攔截〞A 而,A 產生給 B,若能取得 A 的 code,只要把 stderr 換成 stdout 就好了 所以,很明顯:版大問的,不是 由 A 產生 pipe 給 B 008 意見者: Jacob Lee ( 大師 4 級 ) 擅長領域: C&C++ | 作業系統 發表時間: 2009-05-24 08:20:55 [ 檢舉 ] 寫意見 003 ~ 005 時漏引:Novus 也認為:由 A 產生 pipe 給 B 是 case by case 的作法。 而題目:〝攔截pipe前一個程式的stderr〞 及內文:〝B.exe 要怎麼攔截 A.exe的 STD ERR〞 二度表明:不是 A 產生給 B 所以,回答者 002 強週〝絕對〞有解,似乎是對 題目 我的回答 sryang 的作法 OS 運作 不太了解 009 意見者: novus ( 專家 5 級 ) 擅長領域: C&C++ | 物理 發表時間: 2009-05-24 09:30:59 [ 檢舉 ] 補充一下 我的程式示範的就是用 B 攔截 A 的 pipe,完全不需侵入式的做法,也就是說不必動到 A 的 source code。 基本上這和 Windows下的重導完全相同,只是從比較底層的地方著手,因此可以做到比較細微的控制。 010 意見者: novus ( 專家 5 級 ) 擅長領域: C&C++ | 物理 發表時間: 2009-05-24 09:37:59 [ 檢舉 ] 為什麼說有某種程度上需要case by case? 因為並不是所有用console的程式都使用標準的pipe,像我上面的程式要抓 cmd、ping、gcc、gdb 的輸出都沒問題,但是像 telnet 就沒辦法啦。 因為telnet要畫彩色文字,就不是用標準的pipe 011 意見者: DeeR ( 初學者 3 級 ) 發表時間: 2009-05-24 09:59:59 [ 檢舉 ] J 大. 也許您五年前才在玩平行. 小弟也知道, 您的功力不錯. 不過. 有時候. 您也要體會一下, 下頭的這些平民百姓的苦呀. 他們是有問題不會問. 不會用"正規"的表達方式來表達問題. 所以, 不要把一個簡單的問題, 想那麼複雜. 這就像二十幾個博士, 去考初等考, 沒半個考上一樣. 其實, 那些博士真的不懂嗎? 也許, 在某些方面. 懂得比出題的多. 還知道題目封鎖不完全, 會有此題無解或是些題多解出現在單選. 那當然考不上囉. 找知識 搜尋全部 搜尋煩惱 進階搜尋 雅虎資訊 版權所有 (c) 2011 Yahoo! Taiwan. All Rights Reserved. 「本服務設有管理員」 服務條款 隱私權政策 知識+ 之問答內容是由參與Yahoo!奇摩知識+ 之網友提供,僅供參考,Yahoo!奇摩不保證其正確性。 回 · 搞怪電腦基本常識 這一篇文章封面 |
| 本站公告:〔您越需要我們,我們就越有創意〕 | 本站說明書:〔發現故鄉還有改進的地方,請來信告訴原丁們〕 |
| 觀察應用學習點數 :〔咱的故鄉有您的參與,會使我們有更大的發揮空間,展現更豐富精彩的學習畫面〕 | 〔期待藉由無障礙網頁設計,能讓視障小朋友更愛看書、更愛寫作且更愛學習〕:盲用電腦「心得分享」 |