2013-08-26 41 views
0

Fabric(Ubuntu 13.04上的版本1.7.0)遇到了一些问题。使用Fabric嵌套cd调用时发生意外的行为

考虑一下这个功能:

def does_not_work(): 
    with cd('/absolute/folder/one/'): 
    with prefix('change_path_command'): 
     with cd('/absolute/folder/two/'): 
     run('some_random_command') 

我希望它作为执行相同的命令:

def works(): 
    run('cd /absolute/folder/one/ && change_path_command && cd /absolute/folder/two/ && some_random_command') 

然而,这里是fab does_not_work的面料输出:

Requested: some_random_command 
Executed: /bin/bash -l -c "cd /absolute/folder/two/ && change_path_command && some_random_command" 

它似乎嵌套cd s正在引起我的麻烦。

有没有很好的解释?

回答

1

cd context managerprefix context manager不实际运行的命令,当你调用它们,他们只是修改影响的run()和/或任何sudo()后续调用一些地方的环境设置。

所以你run('some_random_command')被执行时,它就会被执行时,它运行在(cd=/folder/oneprefix=change_path_commandcd=/folder/two)的范围内,并且由于内cd优先于外cd,最终的结果是与执行的单个命令cd /folder/two && change_path_command && some_random_command

看看源代码cdprefix到得到的是如何工作的一个更好的想法 - 他们都做最终修改是字典fabric.state.env当他们进入和退出。这些后来在_prefix_commands()的调用中应用,其通过_run_command()函数从run()sudo()调用。

+0

感谢您的回答!在[文档](http://docs.fabfile.org/en/1.7/api/core/context_managers.html#fabric.context_managers.cd)中,他们实际上展示了如何嵌套'cd'命令,但第一个是绝对的,第二个是相对的。我怎样才能实现我想要实现的目标?仅供参考,第一个绝对路径是virtualenv的安装位置,前缀命令是激活virtualenv的'source bin/activate',第二个绝对路径是执行最终命令的位置。 – astorije

相关问题