Debian の debootstrap ユーティリティの Python フロントエンドを書いています。Debootstrap は進捗情報を出力できますが、ファイル記述子 #3 が開いている場合は出力し、この fd に書き込みます。
ヒントはいくつか見つかりましたが、Python でのやり方がわかりませんでした。
Python で fd#3 を作成し、debootstrap サブプロセスを実行して fd#3 から読み取るにはどうすればよいですか?
Debian の debootstrap ユーティリティの Python フロントエンドを書いています。Debootstrap は進捗情報を出力できますが、ファイル記述子 #3 が開いている場合は出力し、この fd に書き込みます。
ヒントはいくつか見つかりましたが、Python でのやり方がわかりませんでした。
Python で fd#3 を作成し、debootstrap サブプロセスを実行して fd#3 から読み取るにはどうすればよいですか?
次のように、低レベルの OS API を使用して fd 3 にパイプを設定する必要があると思います。
import os, sys
# No other fds have been opened, so the lowest available are used (3, 4)
read, write = os.pipe()
# We want the child to write into fd#3, but right now that's the read
# end of the pipe, so do a little switching around:
temp = os.dup(read)
os.dup2(write, read)
os.dup2(temp, write)
os.close(temp)
read, write = write, read # swap actual values to avoid confusion
pid = os.fork()
if pid == 0: # child
os.close(read)
try:
os.execl('/bin/bash', 'bash', '-c', 'echo testing...>&3')
except OSError:
sys.exit(1)
else: # parent
os.close(write)
progress = os.fdopen(read)
print progress.read()
os.wait()
基本的に、パイプを作成し、書き込み終了が fd#3 になるように読み取り/書き込み終了を交換します (利用可能な最も低い fds が使用されるため、まだ他の fd を開いていないことを確認してください)。
次に、親と子で適切なパイプの端をフォークして閉じます。次に、例として使用した私の場合、子でターゲットを実行できbash
ます。親では、パイプの読み取り側の周りに通常のファイルのようなオブジェクトを構築し、低レベルの API を気にせずにそれを進めることができます。
subprocess
パイプの読み取り側に設定するとモジュールを使用できる可能性がありますFD_CLOEXEC
が、パイプを設定するために低レベルの呼び出しを行う必要があるため、そうしてもあまりメリットはありません。