2011-11-04 35 views
13

Trong Vải, khi tôi cố gắng sử dụng bất kỳ bí danh hoặc hàm nào từ tệp .bash_profile của mình, chúng không được nhận dạng. Ví dụ: .bash_profile chứa alias c='workon django-canada', vì vậy khi tôi nhập c trong iTerm hoặc Thiết bị đầu cuối, workon django-canada được thực thi.Tại sao Vải không thấy tệp .bash_profile của tôi?

My fabfile.py chứa

def test(): 
    local('c') 

Nhưng khi tôi cố gắng fab test nó ném này với tôi: [localhost] địa phương: c

/bin/sh: c: command not found 

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

Aborting. 

chức năng Vải khác hoạt động tốt. Tôi có phải chỉ định hồ sơ bash của tôi ở đâu đó trong vải không?

Trả lời

21

EDIT - Khi nó quay ra, điều này đã được khắc phục trong Vải 1.4.4. Từ các thay đổi:

[Tính năng] #725: Cập nhật địa phương để cho phép ghi đè lên vỏ cục bộ nào được sử dụng. Cảm ơn Mustafa Khattab.

Vậy câu hỏi ban đầu sẽ được cố định như thế này:

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

tôi đã để lại câu trả lời ban đầu của tôi dưới đây, mà chỉ liên quan đến Vải phiên bản < 1.4.4.


Vì địa phương không sử dụng bash. Bạn có thể thấy rõ ràng trong đầu ra của mình

/bin/sh: c: command not found 

See? Nó đang sử dụng /bin/sh thay vì /bin/bash. Điều này là do lệnh local của Fabric hoạt động hơi khác một cách nội bộ hơn run. Lệnh local về bản chất là một trình bao bọc xung quanh lớp python subprocess.Popen.

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

Và đây là vấn đề của bạn. Popen mặc định là /bin/sh. Có thể chỉ định một trình bao khác nếu bạn đang gọi chính hàm dựng Popen, nhưng bạn đang sử dụng nó thông qua Fabric. Và thật không may cho bạn, Fabric cho bạn không có phương tiện để vượt qua trong một vỏ, như /bin/bash.

Rất tiếc, không cung cấp cho bạn giải pháp, nhưng nó sẽ trả lời câu hỏi của bạn.

EDIT

Đây là mã trong câu hỏi, kéo trực tiếp từ local chức năng vải của định nghĩa trong operations.py file:

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

Như bạn thấy, nó không vượt qua trong bất cứ điều gì cho từ khóa thực thi . Điều này làm cho nó sử dụng mặc định, là/bin/sh. Nếu nó được sử dụng bash, nó sẽ giống như thế này:

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

Nhưng nó không.Đó là lý do tại sao họ nói những điều sau đây trong tài liệu cho địa phương:

chỉ đơn giản là một trình bao bọc tiện lợi xung quanh việc sử dụng mô-đun con xử lý Python dựng sẵn có vỏ = Đúng kích hoạt. Nếu bạn cần làm bất cứ điều gì đặc biệt, hãy xem xét sử dụng mô-đun subprocess trực tiếp.

+1

Nhưng [Tài liệu vải] (http://docs.fabfile.org/en/0.9.0/usage/env.html#shell) nói: "shell Mặc định: **/bin/bash ** -C- Giá trị được sử dụng làm trình bao bọc vỏ khi thực thi lệnh với lệnh chạy. Phải có thể tồn tại trong biểu mẫu "" - ví dụ: mặc định sử dụng tùy chọn -của Bash giá trị." –

+1

Vâng, các tài liệu đang đề cập đến các lệnh chạy và sudo. Lệnh cục bộ hoạt động khác với lệnh đằng sau hậu trường. Tôi đã chỉnh sửa câu trả lời để hiển thị mã được đề cập. –

+0

Cảm ơn bạn đã làm rõ. Nó rất thông tin –

4

Một workaround chỉ đơn giản là quấn bất cứ lệnh bạn có khoảng một lệnh bash:

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

Nếu bạn cần phải làm rất nhiều trong số này, hãy cân nhắc tạo một custom context manager.

+0

Cảm ơn, công trình này rất tuyệt. –

0

Dường như bạn đang cố sử dụng virtualenvwrapper cục bộ. Bạn sẽ cần phải làm cho chuỗi lệnh cục bộ của bạn trông giống như sau:

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

Đây là ví dụ của bạn thực sự that does that for you in a context manager.

Các vấn đề liên quan