Dae Dae - 5 months ago 23
Python Question

Python Fabric: filter out server output when capturing output of run()

Consider a Linux server which has the following line in the

.bash_profile
of your user:

echo "Hello world"


So, every time you ssh into it, you see
Hello world


Now, consider the following script:

#!/usr/bin/env python
from fabric.api import *

env.hosts = [...]

@task
def test():
with cd('/'):
print run('ls').split()


You'd expect it to output something like:
['tmp', 'etc', 'var', ...]


But the actual output will be:
['Hello', 'world', 'tmp', 'etc', 'var', ...]


Is this a bug in ? Is there any way to suppress server output?

time.sleep()
does not help

Answer

Fabric executes the remote Bash shell in login mode. This causes profile files to be executed. You may see this for yourself by turning on debug mode. On my machine executing your script in debug mode produces the following (among other things)

[x.x.x.x] Executing task 'test'
[x.x.x.x] run: /bin/bash -l -c "cd / && ls"

Notice the -l passed to the remote invocation To overcome this you may override env.shell to remove the -l flag as stated in the linked FAQ.

So change

with cd('/'):

in your code to

with cd('/'), settings(shell='/bin/bash -c'):