Fabric - 有没有办法捕获运行stdout?

时间:2014-01-29 22:06:44

标签: python fabric

我正在尝试执行以下操作:

output = run("ls -l backups")
for line in output.split("/n"):
    do_stuff(line)

stdout ls发送到output的任何方式?


更具体地说,我正在使用一个名为s3cmd的CLI应用程序,它与ls类似,但使用远程Amazon S3存储桶。

不幸的是,ls的替代品无济于事。


6 个答案:

答案 0 :(得分:25)

你要求的正是应该发生的事情。来自docs

  

run会将远程程序的stdout的结果作为单个(可能是多行)字符串返回。

run()以及local()sudo()之类的相关命令会返回一个_AttributeString对象,该对象只是stdout的包装器,可以访问其他信息,例如失败/成功booleans,stderr,命令运行等。结果对象也有一个stdout属性,它更加明确。

要进行问题排查,print type(output), output以确保响应符合您的预期。检查output.failedoutput.stderr。可能是命令没有按照您的预期进行,没有“备份”目录等等。

答案 1 :(得分:17)

使用String IO

尝试以下操作
from fabric.api import *
from StringIO import StringIO

fh = StringIO()
run("ls -l backups", stdout=fh)

for line in fh.readlines():
    do_stuff(line)

答案 2 :(得分:10)

如果你需要使用run(),你可以这样做:

with settings(
    hide('warnings', 'running', 'stdout', 'stderr'),
    warn_only=True
):
    command = 'ls -l backups'
    output = run(command)
    for line in output.splitlines():
        do_stuff(line)

对于local(),有一个更简单的解决方案:

command = 'ls -l backups'
output = local(command, capture=True)
for line in output.splitlines():
    do_stuff(line)

我希望它有所帮助。

答案 3 :(得分:5)

如果您使用local() api,也可以通过设置capture=True

来使用此功能
@task
def login_ecr_docker():
    ecr_login = local("aws ecr get-login --region us-west-2", capture=True)
    docker_login = ecr_login.stdout
    status = local(docker_login, capture=True)
    print (status.stdout)

答案 4 :(得分:2)

使用" \r\n":

尝试拆分
output = run("ls -l backups")
output_stdout = output.stdout.split("\r\n")

答案 5 :(得分:1)

只需简单地返回它:

def output():
    return run("ls -l backups")
a = execute(output, host=hostname)
print a

a将是结果字典。