Easy way to suppress output of fabric run?
Asked Answered
B

6

35

I am running a command on the remote machine:

remote_output = run('mysqldump --no-data --user=username --password={0} database'.format(password))

I would like to capture the output, but not have it all printed to the screen. What's the easiest way to do this?

Bernhardt answered 26/2, 2012 at 19:32 Comment(0)
C
40

It sounds like Managing output section is what you're looking for.

To hide the output from the console, try something like this:

from __future__ import with_statement
from fabric.api import hide, run, get

with hide('output'):
    run('mysqldump --no-data test | tee test.create_table')
    get('~/test.create_table', '~/test.create_table')

Belows is the sample results:

No hosts found. Please specify (single) host string for connection: 192.168.6.142
[192.168.6.142] run: mysqldump --no-data test | tee test.create_table
[192.168.6.142] download: /home/quanta/test.create_table <- /home/quanta/test.create_table
Cameo answered 8/3, 2012 at 17:12 Comment(1)
Edit queue is full, link to the current docs for managing output here. docs.fabfile.org/en/1.12.1/usage/output_controls.htmlOllieollis
W
23

For fabric==2.4.0 you can hide output using the following logic

conn = Connection(host="your-host", user="your-user")
result = conn.run('your_command', hide=True)
result.stdout.strip()  # here you can get the output
Wessel answered 5/11, 2019 at 10:41 Comment(1)
This also works for version 2.5.0 and is probably the official way to hide output in the 2.x series. I is also mentioned shown on the landing page fabfile.org/#how-is-it-used but this feature is not mentioned explicitly in the api docs <docs.fabfile.org/en/2.5/api/…>.. Instead the reader is referred to the docs of the invoke package: docs.pyinvoke.org/en/latest/api/…Lapse
I
21

Try this if you want to hide everything from log and avoid fabric throwing exceptions when command fails:

from __future__ import with_statement
from fabric.api import env,run,hide,settings

env.host_string = 'username@servernameorip'
env.key_filename = '/path/to/key.pem'

def exec_remote_cmd(cmd):
    with hide('output','running','warnings'), settings(warn_only=True):
        return run(cmd)

After that, you can check commands result as shown in this example:

cmd_list = ['ls', 'lss']
for cmd in cmd_list:
    result = exec_remote_cmd(cmd)
    if result.succeeded:
        sys.stdout.write('\n* Command succeeded: '+cmd+'\n')
        sys.stdout.write(result+"\n")
    else:
        sys.stdout.write('\n* Command failed: '+cmd+'\n')
        sys.stdout.write(result+"\n")

This will be the console output of the program (observe that there aren't log messages from fabric):

* Command succeeded: ls
Desktop    espaiorgcats.sql  Pictures   Public     Videos
Documents  examples.desktop  projectes  scripts
Downloads  Music         prueba Templates

* Command failed: lss
/bin/bash: lss: command not found
Informality answered 22/6, 2013 at 11:36 Comment(0)
S
7

As other answers allude, fabric.api doesn't exist anymore (as of writing, fabric==2.5.0) 8 years after the question. However the next most recent answer here implies providing hide=True to every .run() call is the only/accepted way to do it.

Not being satisfied I went digging for a reasonable equivalent to a context where I can specify it only once. It feels like there should still be a way using an invoke.context.Context but I didn't want to spend any longer on this, and the easiest way I could find was using invoke.config.Config, which we can access via fabric.config.Config without needing any additional imports.

>>> import fabric

>>> c = fabric.Connection(
...     "foo.example.com",
...     config=fabric.config.Config(overrides={"run": {"hide": True}}),
... )

>>> result = c.run("hostname")

>>> result.stdout.strip()
'foo.example.com'

Salinasalinas answered 13/12, 2020 at 14:25 Comment(1)
This is the way to do it now, works with Fabric 3.2.Historian
D
0

As of Fabric 2.6.0 hide argument to run is not available.

Expanding on suggestions by @cfillol and @samuel-harmer, using a fabric.Config may be a simpler approach:

   >>> import fabric

   >>> conf = fabric.Config()
   >>> conf.run.hide = True
   >>> conf.run.warn = True

   >>> c = fabric.Connection(
   ...     "foo.example.com",
   ...     config=conf
   ... )

   >>> result = c.run("hostname")

This way no command output is printed and no exception is thrown on command failure.

Dannydannye answered 1/1, 2022 at 23:33 Comment(0)
C
0

As Samuel Harmer also pointed out in his answer, it is possible to manage output of the run command at the connection level.

As of version 2.7.1:

from fabric import Config, Connection

connection = Connection(
      host,
      config = Config(overrides = { 
        "run": { "hide": "stdout" }
      }),
      ...
)
Cardioid answered 16/2, 2023 at 0:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.