在Fabric中,当我尝试使用我的.bash_profile
文件中的任何别名或函数时,它们无法识别.例如我的.bash_profile
包含alias c='workon django-canada'
,所以当我输入c
iTerm或终端时,workon django-canada
执行.
我的fabfile.py
包含
def test(): local('c')
但是当我尝试fab test
它时会向我抛出:[localhost] local:c
/bin/sh: c: command not found Fatal error: local() encountered an error (return code 127) while executing 'c' Aborting.
其他Fabric功能正常.我是否必须在布料的某处指定我的bash配置文件?
编辑 - 事实证明,这是在Fabric 1.4.4中修复的.来自更改日志:
[功能] #725:更新了本地以允许覆盖使用哪个本地shell.感谢Mustafa Khattab.
所以最初的问题将修复如下:
def test(): local('c', shell='/bin/bash')
我在下面留下了原始答案,仅与Fabric版本<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构造函数,则可以指定不同的shell,但是您通过Fabric使用它.不幸的是,Fabric让你无法传递shell,比如/bin/bash
.
对不起,它不能为您提供解决方案,但它应该回答您的问题.
编辑
这是有问题的代码,直接从文件中local
定义的结构函数中提取operations.py
:
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()
但事实并非如此.这就是为什么他们在本地文档中说出以下内容:
local只是一个方便的包装器,使用内置的Python子进程模块,shell = True激活.如果您需要执行任何特殊操作,请考虑直接使用子进程模块.