Kích hoạt virtualenv bằng tập lệnh Python


90

Tôi muốn kích hoạt một phiên bản virtualenv từ một tập lệnh Python.

Tôi biết nó khá dễ thực hiện, nhưng tất cả các ví dụ tôi đã thấy đều sử dụng nó để chạy các lệnh trong env và sau đó đóng quy trình con.

Tôi chỉ muốn kích hoạt virtualenv và quay lại shell, giống như cách mà bin / active làm.

Một cái gì đó như thế này:

$me: my-script.py -d env-name
$(env-name)me:

Điều này có khả thi không?

Liên quan, thích hợp:

virtualenv ›Gọi một env từ một tập lệnh

Câu trả lời:


87

Nếu bạn muốn chạy một quy trình con Python trong virtualenv, bạn có thể làm điều đó bằng cách chạy tập lệnh sử dụng trình thông dịch Python nằm trong thư mục / bin / của virtualenv:

import subprocess

# Path to a Python interpreter that runs any Python script
# under the virtualenv /path/to/virtualenv/
python_bin = "/path/to/virtualenv/bin/python"

# Path to the script that must run under the virtualenv
script_file = "must/run/under/virtualenv/script.py"

subprocess.Popen([python_bin, script_file])

Tuy nhiên, nếu bạn muốn kích hoạt virtualenv dưới trình thông dịch Python hiện tại thay vì một quy trình con, bạn có thể sử dụng activate_this.pytập lệnh:

# Doing execfile() on this file will alter the current interpreter's
# environment so you can import libraries in the virtualenv
activate_this_file = "/path/to/virtualenv/bin/activate_this.py"

execfile(activate_this_file, dict(__file__=activate_this_file))

1
//, Dòng cuối cùng trong khối mã đầu tiên trên câu trả lời này không nên đọc như sau subprocess.Popen([venv_python_file, script_file]):?
Nathan Basanese

// Ngoài ra, có cách nào để chạy script_filetừ một vị trí tùy ý, hay nó phải nằm trong virtualenvthư mục?
Nathan Basanese

Đã sửa, cảm ơn bạn đã thông báo lỗi. Đối với câu hỏi thứ hai của bạn, không nhất script_filethiết phải ở trong thư mục virtualenv, nó có thể ở bất cứ đâu.
Lie Ryan

Làm cách nào để hủy kích hoạt env ảo, nếu tôi đang sử dụng tùy chọn thứ hai?
falsePockets

@falsePockets: XY Vấn đề , tại sao bạn muốn làm điều đó?
Lie Ryan

42

Giải pháp đơn giản nhất để chạy tập lệnh của bạn dưới trình thông dịch của virtualenv là thay thế dòng shebang mặc định bằng đường dẫn đến trình thông dịch của virtualenv như ở đầu tập lệnh:

#!/path/to/project/venv/bin/python

Làm cho tập lệnh có thể thực thi:

chmod u+x script.py

Chạy tập lệnh:

./script.py

Thì đấy!


2
+1 cho sự thanh lịch. Lưu ý trên cửa sổ này đòi hỏi một môi trường phù hợp posix mà hiểu được dòng công việc như Cygwin hay msys
qneill

1
Hoạt động cho python 3.6.3 và windows 10!
toonarmycaptain

Hãy nghĩ rằng tôi có thể đã hiểu sai câu hỏi ban đầu. Anh ta muốn kích hoạt môi trường ảo bằng một script và quay lại shell với môi trường đã được kích hoạt. Câu trả lời của tôi chạy tập lệnh trong môi trường ảo nhưng trình bao trả về không giữ lại môi trường. Giải pháp ngày nay là virtualenvwrapper: virtualenvwrapper.readthedocs.io/en/latest/# . Nó cho phép một người kích hoạt và chuyển đổi giữa các máy ảo khác nhau.
nafooesi

20

Nó chỉ ra rằng, vâng, vấn đề không đơn giản, nhưng giải pháp là.

Đầu tiên tôi phải tạo một kịch bản shell để bọc lệnh "nguồn". Điều đó nói rằng tôi đã sử dụng dấu "." thay vào đó, vì tôi đã đọc rằng tốt hơn là sử dụng nó hơn là nguồn cho các tập lệnh Bash.

#!/bin/bash
. /path/to/env/bin/activate

Sau đó, từ tập lệnh Python của tôi, tôi có thể đơn giản làm điều này:

import os
os.system('/bin/bash --rcfile /path/to/myscript.sh')

Toàn bộ thủ thuật nằm trong --rcfilelập luận.

Khi trình thông dịch Python thoát ra, nó sẽ rời khỏi trình bao hiện tại trong môi trường được kích hoạt.

Thắng lợi!


3
Tôi thực sự không hiểu nó. Tại sao bạn không làm điều đó: os.system('/bin/bash --rcfile path/to/env/activate') Bạn biết đấy, khi một phiên bản bash được bắt đầu, nó sẽ lấy .bashrc làm đối số cho --rcfile. Vì vậy, chỉ cần chỉ định rằng rcfile là tệp kích hoạt của bạn ... Không?
Depado

@Depado Tôi vừa thử giải pháp của bạn và điều này sẽ kích hoạt shell trong python. ít nhất là khi tôi thử nó trong vỏ. >>> os.system ('/ bin / bash --rcfile / var / envs / test / bin / active') (test) tcraig @ heightis-desktop: ~ $ (test) tcraig @ heightis-desktop: ~ $ ls -l tổng 706288
Trenton

Có thể nhưng điều này hoạt động trong một kịch bản Điều bất tiện duy nhất với kỹ thuật này là bạn không nhận được tất cả bí danh và mọi thứ bạn có trong ~ / .bashrc của mình. Nhưng tôi ổn với nó. Ví dụ, lệnh "ls" không có màu. Nhưng mọi thứ đều phù hợp với tôi. Khi tôi muốn rời đi, tôi chỉ cần Ctrl + D
Depado

7
"Khi trình thông dịch python thoát ra, nó sẽ để lại shell hiện tại trong môi trường được kích hoạt" Cái gì? Nó sinh ra một trình bao hoàn toàn mới như một quy trình con và đợi cho đến khi nó kết thúc.
Kos,

Để tránh tạo thêm nhiều tệp mới trên kho lưu trữ của tôi và cũng để sao chép cấu hình bash hiện tại, tôi đã làm điều này:cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
WhyWhat

17

Để chạy một môi trường Python khác theo tài liệu Virtualenv chính thức , trong dòng lệnh, bạn có thể chỉ định đường dẫn đầy đủ đến tệp nhị phân Python thực thi, chỉ cần điều đó (không cần kích hoạt virtualenv trước đó):

/path/to/virtualenv/bin/python

Điều tương tự cũng áp dụng nếu bạn muốn gọi một tập lệnh từ dòng lệnh với virtualenv của mình. Bạn không cần phải kích hoạt nó trước:

me$ /path/to/virtualenv/bin/python myscript.py

Tương tự đối với môi trường Windows (cho dù đó là từ dòng lệnh hay từ tập lệnh):

> \path\to\env\Scripts\python.exe myscript.py

2
Câu hỏi là: Kích hoạt một virtualenv với một kịch bản python (KHÔNG từ Shell)
Zaheer

3
Có, quan điểm của tôi là bạn chỉ có thể gọi thời gian chạy python từ một môi trường ảo mà không cần phải kích hoạt nó trước đó, từ bảng điều khiển hoặc từ một tập lệnh. Tôi sẽ làm rõ câu trả lời, cảm ơn!
Mariano Ruiz

Ôi Chúa ơi! Tôi không nghĩ về nó. đây là giải pháp duy nhất làm việc cho tôi :). Bây giờ, khi tôi đang thực hiện kịch bản python từ php, Tôi đang sử dụng: "path / to / virtualenv / bin / python mypythonscript.py"
Zaheer

6

Chỉ là một giải pháp đơn giản phù hợp với tôi. Tôi không biết tại sao bạn cần tập lệnh Bash về cơ bản thực hiện một bước vô ích (tôi có nhầm không?)

import os
os.system('/bin/bash  --rcfile flask/bin/activate')

Về cơ bản cái nào bạn cần:

[hellsing@silence Foundation]$ python2.7 pythonvenv.py
(flask)[hellsing@silence Foundation]$

Sau đó, thay vì hủy kích hoạt môi trường ảo, chỉ cần Ctrl+ Dhoặc thoát. Đó có phải là một giải pháp khả thi hay đó không phải là điều bạn muốn?


2

Môi trường tiến trình con bị mất ngay khi nó không còn tồn tại, và việc chuyển nội dung môi trường từ đó sang môi trường mẹ là một việc hơi phức tạp.

Bạn có thể cần tạo ra một tập lệnh shell (bạn có thể tạo một tập lệnh động tới / tmp). Nó sẽ xuất các biến môi trường virtualenv vào một tệp, sau đó bạn đọc trong quy trình Python mẹ và đưa vào os.environ.

Hoặc bạn chỉ cần phân tích cú pháp mã kích hoạt đang sử dụng cho dòng đang mở ("bin / active"), trích xuất thủ công nội dung và đưa vào os.environ. Nó là khó, nhưng không phải là không thể.


2
Ý bạn là một cái gì đó như thế này? bitbucket.org/ianb/virtualenv/src/1f9dfb2437f1/…
h3.

2

Câu trả lời hàng đầu chỉ hoạt động cho Python 2.x

Đối với Python 3.x, hãy sử dụng cái này:

activate_this_file = "/path/to/virtualenv/bin/activate_this.py"

exec(compile(open(activate_this_file, "rb").read(), activate_this_file, 'exec'), dict(__file__=activate_this_file))

Tham khảo: Giải pháp thay thế cho tệp thực thi trong Python 3 là gì?



1
@randyPen, tệp active_this.py được tự động thêm vào khi bạn tạo virtualenv trong thư mục dự án của mình. (tức là /project/directory/venv/bin/activate_this.py)
Về mặt lý

-2

Bạn nên tạo tất cả các virtualenvs của mình trong một thư mục, chẳng hạn như virt.

Giả sử tên thư mục virtualenv của bạn là tốt, nếu không thay đổi nó

cd
mkdir custom

Sao chép các dòng dưới đây ...

#!/usr/bin/env bash
ENV_PATH="$HOME/virt/$1/bin/activate"
bash --rcfile $ENV_PATH -i

Tạo một tệp kịch bản shell và dán các dòng trên ...

touch custom/vhelper
nano custom/vhelper

Cấp quyền thực thi cho tệp của bạn:

sudo chmod +x custom/vhelper

Bây giờ hãy xuất đường dẫn thư mục tùy chỉnh đó để bạn có thể tìm thấy nó trên dòng lệnh bằng cách nhấp vào tab ...

xuất PATH = $ PATH: "$ HOME / tùy chỉnh"

Bây giờ bạn có thể sử dụng nó từ mọi nơi chỉ bằng cách gõ lệnh dưới đây ...

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

Giả sử nó là abc thì ...

vhelper abc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.