从Python subprocess执行shell脚本

5
我需要从Python中调用一个shell脚本。 问题是,这个shell脚本会在执行过程中问一些问题,直到完成为止。
我无法找到使用subprocess的方法来做到这一点!(使用pexpect似乎有点过度,因为我只需要启动它并向它发送几个YES)
不要建议需要修改shell脚本的方法!

如果可能的话,您应该创建另一个shell脚本(2),使用eof或read回答您的脚本(1),然后使用Python subprocess.popen执行脚本。 - Rahul Gautam
1
os.system('yes | sed s/y/yes/ | ./myshell.sh') - Elazar
1个回答

8
使用 subprocess 库,您可以这样告诉 Popen 类,要管理进程的标准输入:
import subprocess
shellscript = subprocess.Popen(["shellscript.sh"], stdin=subprocess.PIPE)

现在,shellscript.stdin 是一个类似文件的对象,您可以在其上调用write方法:
shellscript.stdin.write("yes\n")
shellscript.stdin.close()
returncode = shellscript.wait()   # blocks until shellscript is done

您可以通过设置stdout=subprocess.PIPEstderr=subprocess.PIPE来获取进程的标准输出和标准错误,但是不应该同时使用PIPEs作为标准输入和标准输出,因为可能会导致死锁。(请参阅文档。)如果您需要进行管道输入和输出,请使用communicate方法而不是文件对象。
shellscript = subprocess.Popen(["shellscript.sh"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = shellscript.communicate("yes\n")   # blocks until shellscript is done
returncode = shellscript.returncode

stdout和stderr应该在第二个Popen调用中设置,否则.communicate()返回None(没有重定向)。 - jfs
啊,对的——那就是我想说的,但我会编辑答案让它更明确。 (或者,也许你已经编辑过了?无论如何,现在看起来没问题了。) - Jim Pivarski
另外,你可以使用 from subprocess import Popen, PIPE 来避免在代码中频繁使用 subprocess. 前缀,以提高可读性。 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接