![](/img/trans.png)
[英]Python interactive shell not responding to input when run in subprocess
[英]Responding to interactive programs in bash with python subprocess
如果您知道外部脚本的所有答案,那么您可以使用subprocess.run()
并将所有答案(使用\n
)作为一个字符串发送。
对于测试,我使用等待两个值USERNAME
和COLOR
的脚本
#example.sh
printf "Hello, who is running this program? "
read -r USERNAME
echo Hi $USERNAME!
printf "What is your favorite color? "
read -r COLOR
echo I like $COLOR too!
我可以使用单个字符串"Larry\nBlue\n"
一次发送两个值。
import subprocess
cmd = ['sh', 'example.sh']
p = subprocess.run(cmd, input="Larry\nBlue\n".encode(), stdout=subprocess.PIPE)
print( p.stdout.decode() )
它在开始时发送所有内容,外部脚本将第一行作为第一个答案,第二行作为第二个答案,等等。当它完成时,Python 可以获得所有 output -
Hello, who is running this program? Hi Larry!
What is your favorite color? I like Blue too!
并且您可能必须删除不需要的元素。
但是,如果需要从外部脚本的第一个答案中获取 output 来决定发送什么作为下一个答案,那么就会出现问题。
它需要subprocess.Popen()
来运行,同时发送输入并读取 output。 但还有其他问题。 如果外部脚本使用\n
发送行,那么您可以使用readline()
读取它,但如果它不发送\n
则readline()
将等待\n
并且它将阻止 Python 代码。 如果它发送一行,但您将尝试读取 2 行,情况也是如此。 第二个readline()
将阻止它。 所以你必须知道它发送了多少行。
如果你使用read()
那么它会等待数据结束并且它也会阻塞 Python。 If you use read(100)
and output will have 100 bytes (or more) then it will read 100 bytes (and rest will wait for next read()
- but if it will have 99 bytes then read(100)
will block Python.
您必须知道要读取多少字节,或者您必须知道它可以发送什么文本,然后您可以read(1)
,将其添加到缓冲区,并检查缓冲区是否具有您期望的字符串。 这种方法使用了expect
和pyexpect
。
readline()
的第一个示例
我在printf
中使用example.sh
和\n
printf "Hello, who is running this program? \n"
read -r USERNAME
echo Hi $USERNAME!
printf "What is your favorite color? \n"
read -r COLOR
echo I like $COLOR too!
因为example.sh
用\n
发送所以我删除了\n
import subprocess
cmd = ['sh', 'example.sh']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
print('1 >>>', p.stdout.readline().decode().rstrip(), '<<<')
p.stdin.write("Larry!\n".encode())
p.stdin.flush()
print('2 >>>', p.stdout.readline().decode().rstrip(), '<<<')
print('1 >>>', p.stdout.readline().decode().rstrip(), '<<<')
p.stdin.write("Blue!\n".encode())
p.stdin.flush()
print('2 >>>', p.stdout.readline().decode().rstrip(), '<<<')
结果:
1 >>> Hello, who is running this program? <<<
2 >>> Hi Larry!! <<<
1 >>> What is your favorite color? <<<
2 >>> I like Blue! too! <<<
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.