简体   繁体   中英

Fabric - Is there any way to capture run stdout?

I'm trying to do the following:

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

Any way of having the stdout of ls sent to output ?


To be more specific I'm using a CLI app called s3cmd which does something similar to ls , but with remote Amazon S3 buckets.

So a replacement for ls won't help unfortunately.


Exactly what you are asking for should be happening. From the docs :

run will return the result of the remote program's stdout as a single (likely multiline) string.

run() , and related commands like local() and sudo() , return an _AttributeString object that is just a wrapper around stdout with attribute access to additional information like failure/success booleans, stderr, the command run, etc. The result object also has a stdout attribute, which is just more explicit.

To troubleshoot, print type(output), output to be sure the response is what you expect. Examine output.failed and output.stderr . It could be the command isn't doing what you expect, there is no "backups" directory, etc.

Try as below using String IO

from fabric.api import *
from StringIO import StringIO

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

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

In case you need to use run(), you can do it like this:

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)

For local() there is a bit more simple solution:

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

I hope it helps.

You can also use this if you are using the local() api, by setting the 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)

Try split using " \\r\\n ":

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

Just simply return it:

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

a will be dictionary of results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM