I am experiencing some troubles with Fabric (version 1.7.0 on Ubuntu 13.04).
Consider this function:
def does_not_work():
with cd('/absolute/folder/one/'):
with prefix('change_path_command'):
with cd('/absolute/folder/two/'):
run('some_random_command')
I expect it to execute the same command as:
def works():
run('cd /absolute/folder/one/ && change_path_command && cd /absolute/folder/two/ && some_random_command')
However, here is the Fabric output of fab does_not_work
:
Requested: some_random_command
Executed: /bin/bash -l -c "cd /absolute/folder/two/ && change_path_command && some_random_command"
It seems that nesting cd
s is causing me troubles.
Is there a good explanation?
The
cd
context manager and theprefix
context manager don't actually run commands when you invoke them, they just modify some local environment settings that affect any subsequent invocations ofrun()
and/orsudo()
.So when your
run('some_random_command')
gets executed, it gets executed, it runs in the context of (cd=/folder/one
,prefix=change_path_command
,cd=/folder/two
), and since the innercd
takes precedence over the outercd
, the end result is a single command executed withcd /folder/two && change_path_command && some_random_command
.Take a look at the source code for
cd
andprefix
to a get a better idea of how that works -- all they ultimately do is modify the dictionaryfabric.state.env
when they enter and exit. These later get applied in the call to_prefix_commands()
, which gets called fromrun()
andsudo()
via the_run_command()
function.