向bash shell发送多个共享环境的命令
我正在尝试按照这个答案来做:https://stackoverflow.com/a/5087695/343381
我需要在一个环境中执行多个bash命令。我的测试案例很简单:
import subprocess
cmd = subprocess.Popen(['bash'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
# Write the first command
command = "export greeting=hello\n"
cmd.stdin.write(command)
cmd.stdin.flush() # Must include this to ensure data is passed to child process
result = cmd.stdout.read()
print result
# Write the second command
command = "echo $greeting world\n"
cmd.stdin.write(command)
cmd.stdin.flush() # Must include this to ensure data is passed to child process
result = cmd.stdout.read()
print result
我原本期待的结果是(根据参考的答案)能看到“hello world”被打印出来。但实际上发生的情况是,它在第一个 cmd.stdout.read()
这里卡住了,根本没有返回。
有没有人能解释一下为什么 cmd.stdout.read()
从来没有返回?
备注:
- 我必须从python中在同一个环境下运行多个bash命令。因此,subprocess.communicate() 并不适用,因为它会等待进程结束。
- 需要注意的是,在我的实际测试案例中,并不是一组固定的bash命令要执行。逻辑是更动态的。我不能选择一次性运行所有命令。
1 个回答
2
你这里有两个问题:
- 你第一个命令没有任何输出。所以第一次读取会一直等着有输出。
- 你用的是read()而不是readline() -- read()会一直等到有足够的数据才会继续。
下面这个修改过的代码(根据Martjin的建议进行了轮询)运行得很好:
import subprocess
import select
cmd = subprocess.Popen(['bash'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
poll = select.poll()
poll.register(cmd.stdout.fileno(),select.POLLIN)
# Write the first command
command = "export greeting=hello\n"
cmd.stdin.write(command)
cmd.stdin.flush() # Must include this to ensure data is passed to child process
ready = poll.poll(500)
if ready:
result = cmd.stdout.readline()
print result
# Write the second command
command = "echo $greeting world\n"
cmd.stdin.write(command)
cmd.stdin.flush() # Must include this to ensure data is passed to child process
ready = poll.poll(500)
if ready:
result = cmd.stdout.readline()
print result
上面的代码设置了500毫秒的超时,你可以根据需要调整这个时间。