Ткань - Есть ли способ захвата run stdout?

Я пытаюсь сделать следующее:

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

Любой способ, имеющий stdout из ls отправляется output?


Чтобы быть более конкретным, я использую приложение CLI с именем s3cmd которое делает что-то похожее на ls, но с удаленными ведрами Amazon S3.

Так что замена для ls не поможет.


Ответы

Ответ 1

Именно то, что вы просите, должно происходить. Из документов:

run вернет результат удаленной программы stdout как одну (вероятно, многострочную) строку.

run() и связанные с ним команды, такие как local() и sudo(), возвращают объект _AttributeString который является всего лишь оберткой вокруг stdout с доступом к атрибуту дополнительной информации, такой как ошибки /success booleans, stderr, запуск команды и т.д. Объект результата также имеет атрибут stdout, который является более явным.

Чтобы устранить неполадки, print type(output), output чтобы убедиться, что ответ - это то, что вы ожидаете. Изучите output.failed и output.stderr. Может быть, команда не делает то, что вы ожидаете, нет каталога "резервных копий" и т.д.

Ответ 2

Попробуйте, как показано ниже, используя 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)

Ответ 3

Если вам нужно использовать 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)

Я надеюсь, что это помогает.

Ответ 4

Вы также можете использовать это, если используете 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)

Ответ 5

Попробуйте разделить с помощью " \r\n ":

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

Ответ 6

Просто верните его:

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

a будет словарем результатов.