2011-11-04 73 views
13

在Fabric中,当我尝试使用我的.bash_profile文件中的任何别名或函数时,它们无法识别。例如我的.bash_profile包含alias c='workon django-canada',所以当我在iTerm或Terminal中输入c时,执行workon django-canada为什么Fabric没有看到我的.bash_profile?

fabfile.py包含

def test(): 
    local('c') 

但是当我尝试fab test它抛出这个我: [本地主机]地方:C

/bin/sh: c: command not found 

Fatal error: local() encountered an error (return code 127) while executing 'c' 

Aborting. 

其他面料功能正常工作。我必须在面料的某处指定我的bash配置文件吗?

回答

21

编辑 - 事实证明,这是固定在面料1.4.4。来自更新日志:

[功能] #725:更新本地以允许覆盖使用哪个本地shell。感谢穆斯塔法卡塔布。

所以原来的问题将是固定这样的:

def test(): 
    local('c', shell='/bin/bash') 

我已经离开我的下面原来的答复,只涉及到面料版本1.4.4 <。


因为本地不使用bash。您可以在输出中清楚地看到它

/bin/sh: c: command not found 

请参阅?它使用/bin/sh而不是/bin/bash。这是因为Fabric的local命令在内部表现方面与run稍有不同。 local命令本质上是围绕subprocess.Popen python类的包装。

http://docs.python.org/library/subprocess.html#popen-constuctor

这里是你的问题。 Popen默认为/bin/sh。如果您自己调用Popen构造函数,但可以通过Fabric使用它,则可以指定其他shell。不幸的是,织物给你无法通过壳,如/bin/bash

对不起,不提供你的解决方案,但它应该回答你的问题。

编辑

这里是有问题的代码,直接从operations.py文件中定义面料的local功能拉:

p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, 
    stderr=err_stream) 
(stdout, stderr) = p.communicate() 

正如你所看到的,它不会在任何通为可执行文件关键字。这会导致它使用默认值,即/ bin/sh。如果它使用bash,它看起来像这样:

p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream, 
    stderr=err_stream, executable="/bin/bash") 
(stdout, stderr) = p.communicate() 

但它没有。这就是为什么他们在本地文档中说以下内容:

本地只是一个简单的包装使用shell = True激活的内置Python子流程模块。如果您需要做任何特殊的事情,请考虑直接使用子流程模块。

+1

但[Fabric docs](http://docs.fabfile.org/en/0.9.0/usage/env.html#shell)说: “shell 默认值:**/bin/bash ** -l -c 执行例如run命令时用作shell封装器的值必须能够以”的形式存在 - 例如默认使用Bash的-c选项,该命令字符串作为其命令字符串值。” –

+1

是的,文档是指运行命令和sudo。本地命令的作用与幕后的不同。我编辑了答案来显示有问题的代码。 –

+0

谢谢你的澄清。这是非常丰富的 –

4

一种解决方法是简单地包裹你拥有的任何命令周围bash命令:

@task 
def do_something_local(): 
    local("/bin/bash -l -c 'run my command'") 

如果您需要做很多这样的,考虑创建一个custom context manager

+0

谢谢,这个工程很好。 –

0

它看起来像你试图本地使用virtualenvwrapper。你需要让你的本地命令字符串是这样的:

local("/bin/bash -l -c 'workon django-canada && python manage.py runserver'") 

这里是由你真正that does that for you in a context manager一个例子。

相关问题