2012-12-22 29 views
3

Python版本= 2.7時,Windowsstderr重定向到一個任意文件

嗨,

我的Python腳本使用共享的C庫,我想重定向腳本的標準iOS和在一個文件中,如以下示例中的共享C庫(僅限於stderr流)

ç共享庫代碼:

#include <stdio.h> 

void my_print(void) 
{ 
    fprintf(stderr, "This string isn't displayed\n"); 
} 

的Python腳本:

import os, sys, ctypes 

def test(): 
    parserDll = ctypes.CDLL("./titi.dll")   # my shared C library 
    file_stderr_fds = os.open("./toto.txt", 777) # file in which redirect the stderr 
    saved_stderr_fds = os.dup(2)     # Backup stderr 
    os.dup2(file_stderr_fds, 2)      # Redirect stderr to file 
    print >> sys.stderr, "zozo"      # Python test redirect for Python script --> Ok 
    parserDll.my_print(None)      # test for the shared C library --> KO 

if __name__ == "__main__": 
    test() 

當我運行這個Python腳本,在toto.txt文件我看了從共享C庫「ZOZO」(從Python腳本顯示),但一無所獲。但是,如果我評論os.dup2(),兩個字符串都顯示在控制檯中。 爲什麼? 對於使用的Python腳本和共享C庫,標準IO是不是相同?在這種情況下,我該如何重定向到同一個文件?

+0

我認爲兩個stderr流是不同的。所以你應該重定向他們兩個到同一個文件。 – prehistoricpenguin

+0

對於故障隔離,我想我會嘗試從shell中重定向。註釋掉所有重複文件描述符和所有東西的Python代碼。然後,在bash shell中運行'python your-script.py 2&> errors.txt'。這會將stderr重定向到shell級別的文件'errors.txt'。這是否會捕獲您所期望的所有錯誤文本? –

+0

謝謝你的回答。現在很奇怪,但是當使用Visual Studio編譯庫時,shell命令將工作並重定向到一個文件;但是當GCC完成這項工作時,DLL中的字符串不會寫入!無論如何,我真的需要它直接從腳本中直接運行,而不需要任何shell命令,因爲它旨在用於GUI ... –

回答

0

當我在Linux中運行您的示例時,它工作得很好。

大多數情況下,Windows實際上並沒有將POSIX文件描述符用於其實現,因此不會因您對其進行更改而受到影響。我不能說我確切知道Windows'libc實際上是如何實現POSIX文件描述符的,但它可能只是POSIX兼容性功能的一些兼容性層,無論Windows本身使用什麼,並且stdio代碼可能完全不使用它們。

在我看來,作爲一個黑客,無論如何,切換文件描述符在stdio背後。我認爲你應該使用一個明確的FILE *變量,你的C函數可以用來記錄日誌,而你可以用Python的顯式調用來切換。

+0

感謝您的回答。我會歡迎在FILE *中寫入錯誤而不是stderr在python腳本中使用它,而不使用流重定向的想法,但我怎麼能這樣做呢? FILE *可以直接在python的文件對象中檢索嗎? –

+0

你可能可以用ctypes構建'FILE *',但我不確定。我不太熟悉ctypes說。無論哪種方式,你當然可以在C中編寫一個函數,它只需要一個路徑名作爲字符串並打開它,然後從Python中調用該函數。 – Dolda2000

相關問題