python子流程模块在编写标准输出时挂起spark submit命令
我有一个python脚本,用于使用spark提交工具提交spark作业。我想执行命令并将输出实时写入标准输出和日志文件。我正在ubuntu服务器上使用Python2.7 这就是我目前在SubmitJob.py脚本中的内容python子流程模块在编写标准输出时挂起spark submit命令,python,linux,python-2.7,apache-spark,subprocess,Python,Linux,Python 2.7,Apache Spark,Subprocess,我有一个python脚本,用于使用spark提交工具提交spark作业。我想执行命令并将输出实时写入标准输出和日志文件。我正在ubuntu服务器上使用Python2.7 这就是我目前在SubmitJob.py脚本中的内容 #!/usr/bin/python # Submit the command def submitJob(cmd, log_file): with open(log_file, 'w') as fh: process = subprocess.Pope
#!/usr/bin/python
# Submit the command
def submitJob(cmd, log_file):
with open(log_file, 'w') as fh:
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print output.strip()
fh.write(output)
rc = process.poll()
return rc
if __name__ == "__main__":
cmdList = ["dse", "spark-submit", "--spark-master", "spark://127.0.0.1:7077", "--class", "com.spark.myapp", "./myapp.jar"]
log_file = "/tmp/out.log"
exist_status = submitJob(cmdList, log_file)
print "job finished with status ",exist_status
奇怪的是,当我在shell中直接执行相同的命令时,它工作正常,并随着程序的进行在屏幕上生成输出
因此,我使用subprocess.PIPE作为标准输出并编写文件的方式似乎有问题
当前推荐使用子流程模块逐行实时写入标准输出和日志文件的方式是什么?我在网上看到了很多选择,但不确定哪一个是正确的还是最新的
谢谢找出了问题所在。 我试图将两个stdout n stderr重定向到管道以在屏幕上显示。当stderr存在时,这似乎会阻止stdout。如果我从Popen中删除stderr=stdout参数,它就可以正常工作。因此,对于spark submit,您似乎不需要显式重定向stderr,因为它已经隐式地执行了此操作来打印spark日志 可以调用user330612给出的commandList
cmdList = ["spark-submit", "--spark-master", "spark://127.0.0.1:7077", "--class", "com.spark.myapp", "./myapp.jar"]
然后可以使用子流程打印它,记住使用communicate()来防止死锁
警告使用stdout=PIPE和/或stderr=PIPE时死锁,并且子进程生成足够多的输出到管道,从而阻止等待OS管道缓冲区接受更多数据。使用communicate()可以避免这种情况。下面是打印日志的代码
import subprocess
p = subprocess.Popen(cmdList,stdout=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
stderr=stderr.splitlines()
stdout=stdout.splitlines()
for line in stderr:
print line #now it can be printed line by line to a file or something else, for the log
for line in stdout:
print line #for the output
有关子流程和打印行的更多信息,请访问:
您的for循环可能会稍微薄一点,但如果不是这样的话,这就可以了。我不知道spark或者它对stdout有什么作用,但那可能是一个更好的地方。我认为你应该添加一个
spark
标签。还有可能删除bash
标记。有人知道这是spark submit中的错误还是Python模块子进程中的错误吗?我相信这是因为spark submit
将其大量输出重定向到stderr,所以打印到stdout不会得到脚本的实际输出