2011-11-04 74 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一個例子。

相關問題