Python为S3上传生成了awscli进程,它变成了

2024-04-26 23:53:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我的Python应用程序为awsclies3上传创建了一个子流程。在

command = 'aws s3 sync /tmp/tmp_dir s3://mybucket/tmp_dir'
# spawn the process
sp = subprocess.Popen(
    shlex.split(str(command)),
    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# wait for a while
sp.wait()
out, err = sp.communicate()

if sp.returncode == 0:
    logger.info("aws return code: %s", sp.returncode)
    logger.info("aws cli stdout `{}`".format(out))
    return

# handle error

/tmp/tmp_dir为~0.5Gb,包含大约100个文件。 上传过程需要大约25分钟,这是非常缓慢的。在

如果我直接运行AWS命令(不使用Python),只需不到1分钟。在

怎么了?感谢任何帮助。在


Tags: infoawsreturns3dirstdoutoutlogger
1条回答
网友
1楼 · 发布于 2024-04-26 23:53:23

我注意到文档中有一条关于wait()用法的警告(见下文)。但是,与其调试它,为什么不重写它以使用pythonsdk而不是shell输出到awscli呢?也许你会得到更好的性能和更干净的代码。在

https://boto3.readthedocs.io/en/latest/guide/s3.html

Warning This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.

https://docs.python.org/2/library/subprocess.html

编辑3:

这是一个我刚刚测试过的解决方案,它运行时没有阻塞。有一些方便的方法可以在引擎盖下使用wait()或communicate(),这些方法更容易使用,例如check_output:

#!/usr/bin/env python
import subprocess
from subprocess import CalledProcessError

command = ['aws','s3','sync','/tmp/test-sync','s3://bucket-name/test-sync']
try:
    result = subprocess.check_output(command)
    print(result)
except CalledProcessError as err:
    # handle error, check err.returncode which is nonzero.
    pass

相关问题 更多 >