C呼び出しのためにPythonからstdoutをリダイレクトします
-
26-10-2019 - |
質問
これはからのフォローアップの質問です ここ 具体的にはそれに関して 答え.
Pythonモジュールから、私はaを呼び出しています こんにちは世界 単に印刷する実行可能 Hello World
stdoutに。その出力をPythonにリダイレクトすることに興味があります StringIO
そして走りました これ 答えはほとんど私を解決策にもたらします。
この答えの重要な部分は、このコードセグメントです。
1. def redirect_stdout():
2. print "Redirecting stdout"
3. sys.stdout.flush() # <--- important when redirecting to files
4. newstdout = os.dup(1)
5. devnull = os.open('/dev/null', os.O_WRONLY)
6. os.dup2(devnull, 1)
7. os.close(devnull)
8. sys.stdout = os.fdopen(newstdout, 'w')
また、リダイレクトの前にstdoutを復元したいと思います。
質問
- 上記の機能では正確に何が起こっていますか?
- とは
dup
とdup2
やっていますか? - とは
/dev/null
? - 8行目は何をしていますか? (
sys.stdout = os.fdopen(newstdout, 'w')
)
- とは
- stdoutをaに保存するにはどうすればよいですか
StringIO
物体? - 電話の後にstdoutを復元するにはどうすればよいですか こんにちは世界 プログラム?
質問1と3の回答が簡単になるという質問1の答えが得られたら、かなり確信しています。とにかくそれらを投稿して、質問1の答えを私が行きたい方向に押し込むことにしました。
解決
内部で何が起こっているかを明確にする必要があるいくつかの追加のコメントを以下に書いた redirect_stdout
関数:
def redirect_stdout():
print "Redirecting stdout"
sys.stdout.flush() # <--- important when redirecting to files
# Duplicate stdout (file descriptor 1)
# to a different file descriptor number
newstdout = os.dup(1)
# /dev/null is used just to discard what is being printed
devnull = os.open('/dev/null', os.O_WRONLY)
# Duplicate the file descriptor for /dev/null
# and overwrite the value for stdout (file descriptor 1)
os.dup2(devnull, 1)
# Close devnull after duplication (no longer needed)
os.close(devnull)
# Use the original stdout to still be able
# to print to stdout within python
sys.stdout = os.fdopen(newstdout, 'w')
注意すべき重要なことの1つは、プロセスが3つの異なるものを取得することです ファイル記述子 起動時にOSから:
- stdin:0
- stdout:1
- stderr:2
コメントで説明したように、上記のコードは、stdoutのファイル記述子とファイル記述子の複製関数を利用して、Cコードをトリックして別のstdoutを使用し、Pythonコードの元のstdoutへの参照を保持しているため、印刷する。
他のヒント
/dev/null
ブラックホールのように書かれたすべてを飲み込む特別なデバイスファイル(Unixのすべてがファイルです!)です。 dup
ファイル記述子を複製します。 Windowsに慣れている場合、UNIXのファイル記述子は、開いたファイルを表す特別な整数であり、Windowsファイルのハンドルのようなものです。
プログラムが開設されています /dev/null
書き込みの場合(のみ)、ファイル記述子のコピーを取り、開いたファイルを閉じます(ファイル記述子を持つだけでファイルに書き込むのに十分であるため、リソースを開いたままにしておく必要はありません)。にファイル sys.stdout
.
覚えて sys
ファイルシステムなど、あらゆる種類のシステム固有のリソースを表すPythonモジュールです。だから、Unixで sys.stdout
表現します /dev/stdout
つまり、システム STDOUT
ストリーム。
だから、全体として、このコードはPythonをだまして、それを考えさせています /dev/null/
は STDOUT
だから今、あなたのプログラムが書くたびに STDOUT
たとえば、 print
ステートメント(python3の関数)それからそれは本当に書くでしょう /dev/null
そして、コンソールに結果のテキストが表示されることはありません。
見る マニュアルページ これらのPython関数の根底にあるCランタイム関数の場合。
基本的に、彼らはファイル記述子を複製し、新しいファイル記述子( dup()
)または通話で指定されたファイル記述子に dup2()
.