Đổi tên thư mục virtualenv mà không phá vỡ nó


162

Tôi đã tạo thư mục và khởi tạo một thể hiện virtualenv trong đó.

$ mkdir myproject
$ cd myproject
$ virtualenv env

Khi tôi chạy (env)$ pip freeze, nó sẽ hiển thị các gói đã cài đặt.

Bây giờ tôi muốn đổi tên myproject/thành project/.

$ mv myproject/ project/

Tuy nhiên, bây giờ khi tôi chạy

$ . env/bin/activate
(env)$ pip freeze

Nó nói pip không được cài đặt. Làm thế nào để tôi đổi tên thư mục dự án mà không phá vỡ môi trường?


1
Câu hỏi này đã cũ và đã có câu trả lời, nhưng tôi phải tự hỏi, tại sao OP không thể di chuyển virtualenv trở lại vị trí của nó? Rõ ràng điều đó không giải quyết được mong muốn di chuyển / đổi tên, nhưng điều đó sẽ không khôi phục một virtualenv đang hoạt động, hay nó đã bị phá vỡ một cách vô vọng?
Malik A. Rumi

2
Vâng, bạn đã đúng, nó sẽ sửa chữa env ảo, nhưng không giải quyết được vấn đề.
Florian

Tháng 11 năm 2019, Python3. Giải pháp tốt nhất cho tôi là mô tả trong aarongorka.com/blog/portable-virtualenv
Samir Sadek

Câu trả lời:


148

Bạn cần điều chỉnh cài đặt của mình để sử dụng các đường dẫn tương đối. virtualenvcung cấp cho điều này với --relocatabletùy chọn. Từ các tài liệu :

Thông thường môi trường được gắn với một con đường cụ thể. Điều đó có nghĩa là bạn không thể di chuyển một môi trường xung quanh hoặc sao chép nó sang một máy tính khác. Bạn có thể sửa một môi trường để làm cho nó có thể di chuyển được bằng lệnh:

$ virtualenv - ENV tương thích

LƯU Ý: ENV là tên của môi trường ảo và bạn phải chạy nó từ bên ngoài thư mục ENV.

Điều này sẽ làm cho một số tệp được tạo bởi setuptools hoặc phân phối sử dụng các đường dẫn tương đối và sẽ thay đổi tất cả các tập lệnh để sử dụng activ_this.py thay vì sử dụng vị trí của trình thông dịch Python để chọn môi trường.

Lưu ý: bạn phải chạy nó sau khi bạn đã cài đặt bất kỳ gói nào vào môi trường. Nếu bạn tạo một môi trường có thể định vị lại, sau đó cài đặt gói mới, bạn phải chạy virtualenv - Relocitable một lần nữa.


2
Hãy cẩn thận: Thay đổi một env để di chuyển không chỉ cho phép bạn di chuyển thư mục. (xem Lưu ý: được sao chép từ các tài liệu) ... nó có thể có tác dụng phụ.
Ben Roberts

7
Tùy chọn --relocitable hiện có một số vấn đề và không được đảm bảo để hoạt động trong mọi trường hợp. Có thể tùy chọn này sẽ không được chấp nhận trong phiên bản tương lai của virtualenv. Ngoài ra, điều này không làm cho các gói của bạn đa nền tảng. Bạn có thể di chuyển thư mục xung quanh, nhưng nó chỉ có thể được sử dụng trên các máy tính tương tự khác.
Demz

1
@TheDemz grep -EIr '\Wold_venv_name\W' /path/to/new_venvsẽ giúp tìm bất kỳ shabang nào sử dụng venv cũ, nhưng không phải là một xác minh đầy đủ của venv di dời.
hobs

2
Ngoài ra, bạn sẽ phải chỉnh sửa .projecttệp virtualenvwrapper , chứa đường dẫn đến mã nguồn phụ thuộc vào virtualenv, giả sử bạn đang sử dụng virutalenvwrapper và cũng đã đổi tên thư mục dự án để khớp với virtualenv mới.
hobs

Tôi đã phải hủy kích hoạt virtualenv trước khi chạy nó.
antonagestam

108

Tôi tin rằng "biết tại sao" quan trọng hơn "biết cách" . Vì vậy, đây là một cách tiếp cận khác để khắc phục điều này.

Khi bạn chạy . env/bin/activate, nó thực sự thực thi các lệnh sau ( /tmpví dụ sử dụng ):

VIRTUAL_ENV="/tmp/myproject/env"
export VIRTUAL_ENV

Tuy nhiên, bạn vừa đổi tên myprojectđể project, do đó, lệnh rằng thất bại trong việc thực thi. Đó là lý do tại sao nó nói pip is not installed, bởi vì bạn chưa cài đặt piptrong môi trường toàn cầu của hệ thống và virtualenv của bạn pipkhông có nguồn gốc chính xác.

Nếu bạn muốn sửa lỗi này bằng tay, đây là cách:

  1. Với trình chỉnh sửa yêu thích của bạn như Vim, /tmp/project/env/bin/activatethường sửa đổi trong dòng 42:

    VIRTUAL_ENV='/tmp/myproject/env' => VIRTUAL_ENV='/tmp/project/env'

  2. Sửa đổi /tmp/project/env/bin/piptrong dòng 1:

    #!/tmp/myproject/env/bin/python => #!/tmp/project/env/bin/python

Sau đó, kích hoạt lại môi trường ảo của bạn envvà bạn sẽ thấy bạn pipđã quay trở lại.


6
Nếu thay đổi thủ công các đường dẫn là mong muốn, thì cần lưu ý rằng có nhiều hơn hai tệp được mã hóa cứng. Tìm tất cả chúng với một cái gì đó như : grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name. Trên thực tế, tôi nhận thấy rằng trong một trong những phiên bản Django của tôi, rất nhiều gói có "đường dẫn đến Python sh-bang" trong đó.
Kevin

Điều này đã giúp tôi rất nhiều. Tôi chắc chắn cần phải biết tại sao ... Cảm ơn!
Jarvis

Trái ngược với nhận xét của Keven ở trên, tôi thấy rằng việc chỉnh sửa hai dòng này giải quyết tất cả các vấn đề cho tôi liên quan đến việc di chuyển virtualenv. Có lẽ có một số trường hợp sử dụng mà tôi không sử dụng và vì vậy không gặp phải vấn đề.
Deleet

Cào đó! Hôm nay tôi gặp phải một vấn đề: ipython sẽ không hoạt động trong virtualenv. Để giải quyết nó, tôi đã chỉnh sửa tiêu đề bash (nó được gọi là gì?) Trong ipythontệp và sau đó nó hoạt động tốt.
Deleet 4/11/2016

Hmm, điều này không hiệu quả với tôi và có vẻ như tập lệnh kích hoạt của tôi không có Dòng 1 được đề cập ở đây trong Bước 2. Đã làm gì đó thay đổi?
Evan Zamir

40

LƯU Ý: Như @jb. chỉ ra, giải pháp này chỉ áp dụng cho dễ dàng (tái) tạo virtualenv. Nếu một môi trường mất vài giờ để cài đặt giải pháp này thì không nên


Virtualenvs rất tuyệt vì chúng dễ dàng thực hiện và chuyển đổi; họ giữ cho bạn khỏi bị khóa vào một cấu hình duy nhất. Nếu bạn biết các yêu cầu của dự án hoặc có thể nhận được chúng, hãy tạo một cái mớivirtualenv :

  • Tạo một requirements.txttập tin

    (env)$ pip freeze > requirements.txt

    • Nếu bạn không thể tạo requirements.txttệp, hãy kiểm tra env/lib/pythonX.X/site-packagestrước khi xóa bản gốc env.
  • Xóa cái hiện có (env)

    deactivate && rm -rf env

  • Tạo một cái mới virtualenv, kích hoạt nó và cài đặt các yêu cầu

    virtualenv env && . env/bin/activate && pip install -r requirements.txt


Ngoài ra, sử dụng virtualenvwrapper để làm cho mọi thứ dễ dàng hơn một chút vì tất cả các virtualenv được giữ ở một vị trí tập trung

$(old-venv) pip freeze > temp-reqs.txt
$(old-venv) deactivate
$ mkvirtualenv new-venv
$(new-venv) pip install -r temp-reqs.txt
$(new-venv) rmvirtualenv old-venv

6
Đối với một số người pip install -r requirements.txtmất vài giờ (biên dịch phần mở rộng C của bên thứ ba trên raspberry pi).
jb.

4
Có lẽ đúng, nhưng đó có vẻ như là một trường hợp cạnh với tôi. Tôi vẫn nghĩ rằng đây có thể là một giải pháp khả thi cho nhiều trường hợp.
bnjmn

Yah, nhiều dự án (ví dụ trang web Django) chỉ mất 30 giây để cài đặt mọi thứ, ngay cả khi chúng có vài chục phụ thuộc (miễn là bạn tải xuống mọi thứ trước và sử dụng '--no-index --find-links = downloadDir' )
Jonathan Hartley

1
@bnjmn một lớp lót virtualenv env && pip install -r requirements.txtsẽ KHÔNG cài đặt các yêu cầu trong môi trường mới vì bạn không kích hoạt nó
Yarin

1
@Yarin Cảm ơn bạn đã chỉ ra điều đó. Tôi hoàn toàn bỏ lỡ nó, là chính virtualenv-wrapperngười dùng (tự động kích hoạt khi tạo). Tôi đã cập nhật câu trả lời của mình để bao gồm kích hoạt với virtualenvhy vọng tránh mọi sự nhầm lẫn.
bnjmn

28

Tôi luôn cài đặt virtualenvwrapper để giúp đỡ. Từ dấu nhắc shell:

pip install virtualenvwrapper

Có một cách được ghi lại trong các tài liệu virtualenvwrapper - cpvirtualenv Đây là những gì bạn làm. Hãy chắc chắn rằng bạn đã ra khỏi môi trường của mình và quay lại dấu nhắc shell. Nhập vào đây với tên yêu cầu:

cpvirtualenv oldenv newenv

Và sau đó, nếu cần thiết:

rmvirtualenv oldenv

Để đi đến newenv của bạn:

workon newenv

1
Câu trả lời của Afiances thực sự nên là phương pháp được chấp nhận.
Jaxian

Điều này chỉ hoạt động nếu một người đang sử dụng virtualenvwrapper, không chỉ virtualenv. Câu trả lời này từ @ryankdwyer là tốt hơn.
LS

Tôi đã chỉnh sửa câu trả lời của mình để phản ánh rằng người ta nên cài đặt 'virtualenvwrapper'. Giả sử rằng việc đổi tên môi trường ảo xảy ra rất nhiều, tôi sẽ khuyên bạn nên dùng cách này.
Af giáp

Mặc dù nó dựa vào virtualenvwrapper, nhưng nó là đơn giản nhất. Và nó hoạt động tốt.
blasrodri

17

Bạn có thể khắc phục sự cố của mình bằng cách thực hiện theo các bước sau:

  1. đổi tên thư mục của bạn
  2. chạy lại cái này: $ virtualenv ..\path\renamed_directory
  3. virtualenv sẽ sửa các liên kết thư mục trong khi để các gói của bạn vào vị trí
  4. $ scripts/activate
  5. $ pip freeze để xác minh các gói của bạn được đặt đúng chỗ
  6. Một cảnh báo quan trọng, nếu bạn có bất kỳ phụ thuộc đường dẫn tĩnh nào trong các tệp script trong thư mục virtualenv của mình, bạn sẽ phải thay đổi chúng theo cách thủ công.

1
Đây là một giải pháp rất tốt cho tôi. Vì giải pháp này có thể tránh được một số vấn đề liên quan --relocatable, tôi nghĩ giải pháp này tốt hơn câu trả lời được chấp nhận. Cho đến nay, tôi nhận thấy rằng nhiều .pyctập tin _new_name_/lib/python2.7vẫn tham khảo _old_name_. Tuy nhiên, điều đó dường như không ảnh hưởng đến cách môi trường của tôi hoạt động. Có lẽ giải pháp tốt hơn là sử dụng virtualenvwrapperhoặc một số tiện ích khác được đề cập trong số các câu trả lời ở đây. Ít nhất giải pháp này không yêu cầu cài đặt các chương trình bổ sung.
LS

Hoạt động như một lá bùa!
AmirHossein

13

Một cách khác để làm điều đó hiệu quả với tôi nhiều lần mà không gặp vấn đề gì là virtualenv-clone :

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env

Điều này nên được đánh dấu là câu trả lời tốt nhất. Bỏ tay xuống! Phải mất một thời gian để nhân bản, vì vậy hãy kiên nhẫn.
Amitrajit Bose

virtualenv-clone bỏ qua để cập nhật lời nhắc. Phải đi làm một cách thủ công. Khác với những gì tuyệt vời của nó.
dùng3667349

5

(bên trong thư mục dự án)

cd bin
sed -i 's/old_dir_name/new_dir_name/g' *

Đừng quên tắt và kích hoạt


Hoạt động tốt; Hoặc đối với đường dẫn Linux:sed -i "s|$old_dir|$new_dir|g" bin/*
Phá hủy

sed -i '.original' 's/old_dir_name/new_dir_name/g' *cho máy Mac
Alex

1

virtualenv --relocatable ENVkhông phải là một giải pháp mong muốn. Tôi cho rằng hầu hết mọi người muốn có khả năng đổi tên một virtualenv mà không có bất kỳ tác dụng phụ lâu dài nào.

Vì vậy, tôi đã tạo ra một công cụ đơn giản để làm việc đó. Trang dự án cho virtualenv-mv phác thảo chi tiết hơn một chút, nhưng về cơ bản, bạn có thể sử dụng virtualenv-mvgiống như bạn sử dụng một triển khai đơn giản mv(không có bất kỳ tùy chọn nào).

Ví dụ:

virtualenv-mv myproject project

Xin lưu ý tuy nhiên tôi vừa hack cái này. Nó có thể bị hỏng trong những trường hợp bất thường (ví dụ như virtualenvs được liên kết), vì vậy hãy cẩn thận (sao lưu những gì bạn không đủ khả năng để mất) và cho tôi biết nếu bạn gặp phải bất kỳ vấn đề nào.

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.