sys.stdout.write()関数を使用した印刷に関する宿題の割り当てに問題があります。私がしなければならないのは、stdin/stdoutリダイレクションとパイプラインをサポートする単純なシェルを実装することです。下のコードでは、私のプログラム "ch.py"から、入力を要求する "%%"が、入力された式にパイプラインが含まれている間違った時刻に出力されるように見えるという問題があります。例えばsys.stdout.write()は、Pythonのパイプラインで間違ったタイミングで印刷します。
、私が入力した場合、 "-name ch.pyを見つける| grepのインポートをxargsの"、私が取得したいことは次のとおりです。
%% find -name ch.py | xargs grep import
import os
import sys
import shlex
%%
しかし、私は実際に取得することです:
%% find -name ch.py | xargs grep import
%% import os
import sys
import shlex
"ls"や "cat ch.py"のように入力にパイプラインが含まれていないときは問題がないので、メインプロセスはすべての子プロセスが完了するのを待たずに続行すると思います。私は引数の他の組み合わせと "os.waitpid()"を呼び出すか、代わりに "os.wait()"を使用してみましたが、問題を修正するものは何もありません。
私が間違っていることを誰かに教えてもらえますか?
import os
import sys
import shlex
def main():
while True:
sys.stdout.write("%% ")
sys.stdout.flush()
user_input = sys.stdin.readline()
if user_input:
parsed_input, to_write = parse(user_input)
else: # user pressed Ctrl+D, exit program
sys.stdout.write("Bye!\n")
sys.exit(0)
pid = os.fork()
if pid == 0: # EVALUATION PROCESS
if to_write: # if stdout redirection
os.dup2(to_write, 1) # write in file instead of stdout
os.close(to_write)
evaluate(parsed_input, len(parsed_input)-1)
elif pid > 0: # MAIN PROCESS
os.waitpid(pid, 0) # wait for evaluation to complete
def evaluate(parsed_input, pipe_count):
if pipe_count == 0:
# execute leftmost command of the expression
os.execvp(parsed_input[0][0], parsed_input[0])
elif pipe_count > 0:
r, w = os.pipe()
pid = os.fork()
if pid == 0: # CHILD
os.close(w)
os.dup2(r, 0) # read from pipeline instead of stdin
os.close(r)
# execute right side of the pipeline
os.execvp(parsed_input[-1][0], parsed_input[-1])
elif pid > 0: # PARENT
os.close(r)
os.dup2(w, 1) # write in pipeline instead of stdout
os.close(w)
# evaluate left side of the pipeline
evaluate(parsed_input[:-1], pipe_count-1)
'evaluate()'に 'os.fork()'の結果として得られるpidも待つべきです。 'main()'の最初のforkに対してのみwaitpid()を呼び出します。したがって、 'pipe_count'> 0の場合、' evaluate() 'で作成されたプロセスのどれかを待つことに失敗します。 –
あなたの助けてくれてありがとう!親と子が '評価する 'ことを逆転した後、親はすべての子どもたちが完了するのを待つことができ、問題は修正されました。 –