web-dev-qa-db-fra.com

Fabric - Existe-t-il un moyen de capturer run stdout?

J'essaie de faire ce qui suit:

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

Est-il possible d'envoyer le stdout de ls à output?


Pour être plus précis, j'utilise une application CLI appelée s3cmd qui fait quelque chose de similaire à ls, mais avec des compartiments Amazon S3 distants.

Un remplacement de ls n'aidera donc malheureusement pas.


31
RadiantHex

Exactement ce que vous demandez devrait se produire. De la docs :

run renverra le résultat de la sortie standard du programme distant sous la forme d'une chaîne unique (probablement multiligne).

run(), et les commandes associées comme local() et Sudo(), renvoient un objet _AttributeString qui n'est qu'un wrapper autour de stdout avec un accès attributaire à des informations supplémentaires comme les échecs/succès booléens, stderr, l'exécution de la commande, etc. L'objet résultat a également un attribut stdout, qui est juste plus explicite.

Pour dépanner, print type(output), output pour être sûr que la réponse est celle que vous attendez. Examinez output.failed Et output.stderr. Il se peut que la commande ne fasse pas ce que vous attendez, il n'y a pas de répertoire "sauvegardes", etc.

26
JCotton

Essayez comme ci-dessous en utilisant 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)
17
user1406490

Si vous devez utiliser run (), vous pouvez le faire comme ceci:

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)

Pour local (), il existe une solution un peu plus simple:

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

J'espère que ça aide.

12
Evhz

Vous pouvez également l'utiliser si vous utilisez l'api local(), en définissant 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
pitaside

Essayez de diviser en utilisant "\r\n ":

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

Il suffit de le retourner:

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

un sera un dictionnaire de résultats.

1
Bekzot Asimov