How to set the working directory for a Fabric task?
Asked Answered
M

2

28

Assuming I define a trivial task to list files on a remote server:

from fabric.api import run, env

env.use_ssh_config = True

def list_files():
    run('ls')

And I execute it with:

fab -H server list_files

How can I specify the working directory for the command I'm running, other than doing:

run('cd /tmp && ls')

Which doesn't look very idiomatic to me?

Disclaimer: I'm looking at Fabric for the first time in my life and I'm totally new to Python.

Millham answered 23/4, 2012 at 12:56 Comment(1)
be sure you take a look at the tutorial, this very question is covered in there.Cumin
C
49

Use the Context Manager cd:

from fabric.api import run, env
from fabric.context_managers import cd

env.use_ssh_config = True

def list_files():
    with cd('/tmp'):
        run('ls')
Clustered answered 23/4, 2012 at 14:1 Comment(3)
But what if I want all of my run commands to run in the same directory? Will I have to wrap my entire fabfile in a with cd()? Is there not something like env.working_dir = '/my/dir'?Middlebuster
@Middlebuster if you don't want a huge block wrapped in a context manager, put all the black into a separate function and wrap call to this function into the context manager.Munn
Note that the Context object now is contained within InvokeSamaniego
A
23

Answer for fabric 2.4.0 looks like this:

from fabric import Connection

conn = Connection(host=HOST_NAME, user=USER_NAME, connect_kwargs={'password': PASSWORD})

with conn.cd('/tmp/'):
    conn.run('ls -la')

This is not covered by the fabric documentation but by the invoke documentation.

Alicaalicante answered 23/12, 2018 at 10:38 Comment(1)
The fabric documentation suggests doing with Connection('host') as c:, so would you nest the with statements inside of each other? with Connection('host') as c: with c.cd('/tmp/'):Gilletta

© 2022 - 2024 — McMap. All rights reserved.