在 Fabric 中,当我尝试使用我的 .bash_profile
文件中的任何别名或函数时,它们无法被识别。例如,我的 .bash_profile
包含 alias c='workon django-canada'
,所以当我在 iTerm 或终端中键入 c
时, workon django-canada
被执行。
我的 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.
其他 Fabric 函数工作正常。我必须在结构中的某处指定我的 bash 配置文件吗?
最佳答案
编辑 - 事实证明,这已在 Fabric 1.4.4 中修复。来自变更日志:
[Feature] #725: Updated local to allow override of which local shell is used. Thanks to 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
。
抱歉,没有为您提供解决方案,但它应该可以回答您的问题。
编辑
这是有问题的代码,直接从 operations.py
文件中定义的 fabric 的 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()
但事实并非如此。这就是为什么他们在本地文档中说以下内容:
local is simply a convenience wrapper around the use of the builtin Python subprocess module with shell=True activated. If you need to do anything special, consider using the subprocess module directly.
关于fabric - 为什么 Fabric 看不到我的 .bash_profile?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8005348/