เปิดใช้งาน Virtualenv ด้วยสคริปต์ Python


91

ฉันต้องการเปิดใช้งานอินสแตนซ์ Virtualenv จากสคริปต์ Python

ฉันรู้ว่ามันค่อนข้างง่ายที่จะทำ แต่ตัวอย่างทั้งหมดที่ฉันเห็นใช้เพื่อเรียกใช้คำสั่งภายใน env แล้วปิดกระบวนการย่อย

ฉันแค่ต้องการเปิดใช้งาน Virtualenv และกลับไปที่เชลล์แบบเดียวกับที่ bin / เปิดใช้งานทำ

สิ่งนี้:

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

เป็นไปได้หรือไม่

เกี่ยวข้อง:

Virtualenv› การเรียก env จากสคริปต์

คำตอบ:


88

หากคุณต้องการรันกระบวนการย่อย Python ภายใต้ Virtualenv คุณสามารถทำได้โดยการรันสคริปต์โดยใช้ตัวแปล Python ที่อยู่ภายในไดเร็กทอรี / bin / ของ 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])

อย่างไรก็ตามหากคุณต้องการเปิดใช้งาน Virtualenv ภายใต้ตัวแปล Python ปัจจุบันแทนกระบวนการย่อยคุณสามารถใช้activate_this.pyสคริปต์:

# 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
//, บรรทัดสุดท้ายในบล็อกโค้ดแรกของคำตอบนี้ไม่ควรอ่านดังนี้: subprocess.Popen([venv_python_file, script_file])?
Nathan Basanese

// นอกจากนี้ยังมีวิธีเรียกใช้script_fileจากตำแหน่งที่กำหนดเองหรือไม่หรือต้องอยู่ในvirtualenvไดเรกทอรี?
Nathan Basanese

แก้ไขแล้วขอบคุณที่สังเกตเห็นข้อผิดพลาด สำหรับคำถามที่สองของคุณscript_fileไม่จำเป็นต้องอยู่ในไดเร็กทอรี Virtualenv ก็สามารถทำได้ทุกที่
Lie Ryan

ฉันจะปิดการใช้งาน virtual env ได้อย่างไรถ้าฉันใช้ตัวเลือกที่สอง
falsePockets

@falsePockets: ปัญหา XYทำไมคุณถึงต้องการทำเช่นนั้น?
Lie Ryan

42

วิธีแก้ปัญหาที่ง่ายที่สุดในการรันสคริปต์ของคุณภายใต้ตัวแปลของ Virtualenv คือการแทนที่บรรทัด Shebang เริ่มต้นด้วยพา ธ ไปยังล่ามของ Virtualenv เช่นนี้ในตอนต้นของสคริปต์:

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

ทำให้สคริปต์ทำงานได้:

chmod u+x script.py

เรียกใช้สคริปต์:

./script.py

โวลา!


2
+1 เพื่อความสง่างาม หมายเหตุเกี่ยวกับ windows สิ่งนี้ต้องการสภาพแวดล้อมที่สอดคล้องกับ posix ที่เข้าใจสาย shebang เช่น cygwin หรือ msys
qneill

1
ใช้ได้กับ python 3.6.3 และ windows 10!
toonarmycaptain

คิดว่าฉันอาจจะเข้าใจคำถามเดิมผิด เขาต้องการเปิดใช้งานสภาพแวดล้อมเสมือนด้วยสคริปต์และกลับไปที่เชลล์ด้วยสภาพแวดล้อมที่เปิดใช้งาน คำตอบของฉันเรียกใช้สคริปต์ในสภาพแวดล้อมเสมือน แต่เชลล์ที่ส่งคืนไม่เก็บสภาพแวดล้อม วิธีการแก้ปัญหาวันที่ทันสมัยเป็น virtualenvwrapper: virtualenvwrapper.readthedocs.io/en/latest/# ช่วยให้สามารถเปิดใช้งานและสลับไปมาระหว่างอัจฉริยะที่แตกต่างกัน
nafooesi

20

ปรากฎว่าใช่ปัญหาไม่ง่าย แต่วิธีแก้ปัญหาคือ

ก่อนอื่นฉันต้องสร้างเชลล์สคริปต์เพื่อรวมคำสั่ง "source" ที่บอกว่าฉันใช้เครื่องหมาย "." แทนเพราะฉันอ่านแล้วว่าดีกว่าที่จะใช้ซอร์สสำหรับสคริปต์ Bash

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

จากสคริปต์ Python ของฉันฉันสามารถทำได้:

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

เคล็ดลับทั้งหมดอยู่ในการ--rcfileโต้แย้ง

เมื่อล่าม Python ออกจากเชลล์ปัจจุบันในสภาพแวดล้อมที่เปิดใช้งาน

ชนะ!


3
ฉันไม่เข้าใจจริงๆ ทำไมคุณไม่ทำอย่างนั้น: os.system('/bin/bash --rcfile path/to/env/activate') คุณรู้ไหมว่าเมื่อเริ่มต้นอินสแตนซ์ของ bash จะใช้. bashrc เป็นอาร์กิวเมนต์สำหรับ --rcfile ดังนั้นเพียงระบุว่า rcfile เป็นไฟล์เปิดใช้งานของคุณ ... ไม่ใช่?
Depado

@Depado ฉันเพิ่งลองใช้วิธีแก้ปัญหาของคุณและสิ่งนี้จะเปิดใช้งานเชลล์ภายใน python อย่างน้อยเมื่อฉันลองใช้มันในเปลือก >>> os.system ('/ bin / bash --rcfile / var / envs / test / bin / enable') (ทดสอบ) tcraig @ tallis-desktop: ~ $ (ทดสอบ) tcraig @ tallis-desktop: ~ $ ls -l รวม 706288
เทรนตัน

อาจจะใช้งานได้ในสคริปต์ สิ่งเดียวที่ไม่สะดวกกับเทคนิคนี้คือคุณไม่ได้รับนามแฝงทั้งหมดและทุกสิ่งที่คุณมีใน ~ / .bashrc ของคุณ แต่ฉันสบายดีกับมัน ตัวอย่างเช่นคำสั่ง "ls" ไม่มีสี แต่ทุกอย่างใช้ได้ผลสำหรับฉัน เมื่อฉันต้องการออกฉันเพียง Ctrl + D
Depado

7
"เมื่อล่ามหลามออกจากเชลล์ปัจจุบันในสภาพแวดล้อมที่เปิดใช้งาน" อะไร? มันสร้างเชลล์ใหม่ทั้งหมดเป็นกระบวนการย่อยและรอจนกว่าจะเสร็จสิ้น
Kos

เพื่อหลีกเลี่ยงการสร้างไฟล์ใหม่เพิ่มเติมในที่เก็บของฉันและเพื่อจำลองการกำหนดค่า bash ปัจจุบันฉันจึงทำสิ่งนี้:cat ~/.bashrc env/bin/activate > env/bin/activate2 && /bin/bash --rcfile env/bin/activate2
WhyWhat

17

ในการเรียกใช้สภาพแวดล้อม Python อื่นตามเอกสาร Virtualenvอย่างเป็นทางการในบรรทัดคำสั่งคุณสามารถระบุเส้นทางแบบเต็มไปยังไบนารี Python ที่ปฏิบัติการได้เพียงแค่นั้น (ไม่จำเป็นต้องใช้งาน Virtualenv ก่อน):

/path/to/virtualenv/bin/python

เช่นเดียวกับหากคุณต้องการเรียกใช้สคริปต์จากบรรทัดคำสั่งด้วย Virtualenv ของคุณ คุณไม่จำเป็นต้องเปิดใช้งานก่อน:

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

เช่นเดียวกันสำหรับสภาพแวดล้อม Windows (ไม่ว่าจะมาจากบรรทัดคำสั่งหรือจากสคริปต์):

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

2
คำถามคือ: เปิดใช้งาน Virtualenv ด้วยสคริปต์ python (ไม่ใช่จาก Shell)
Zaheer

3
ใช่ประเด็นของฉันคือคุณสามารถเรียก python runtime จากสภาพแวดล้อมเสมือนได้โดยไม่จำเป็นต้องเปิดใช้งานก่อนจากคอนโซลหรือจากสคริปต์ ฉันจะชี้แจงคำตอบขอบคุณ!
Mariano Ruiz

คุณพระช่วย! ฉันไม่ได้คิดเกี่ยวกับมัน นี่เป็นทางออกเดียวที่ใช้ได้ผลสำหรับฉัน :) ตอนนี้เมื่อฉันเรียกใช้สคริปต์ python จาก php ฉันกำลังใช้: "path / to / Virtualenv / bin / python mypythonscript.py"
Zaheer

6

เพียงวิธีง่ายๆที่เหมาะกับฉัน ฉันไม่รู้ว่าทำไมคุณต้องใช้สคริปต์ Bash ซึ่งโดยพื้นฐานแล้วเป็นขั้นตอนที่ไร้ประโยชน์ (ฉันผิดหรือเปล่า)

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

ซึ่งโดยพื้นฐานแล้วสิ่งที่คุณต้องการ:

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

จากนั้นแทนที่จะปิดใช้งานสภาพแวดล้อมเสมือนเพียงแค่Ctrl+ Dหรือออก นั่นเป็นทางออกที่เป็นไปได้หรือไม่ใช่สิ่งที่คุณต้องการ?


2

สภาพแวดล้อมกระบวนการย่อยจะหายไปในช่วงเวลาที่ไม่มีอยู่และการย้ายเนื้อหาสภาพแวดล้อมจากที่นั่นไปยังพาเรนต์นั้นค่อนข้างยุ่งยาก

คุณอาจต้องวางเชลล์สคริปต์ (คุณสามารถสร้างหนึ่งแบบไดนามิกเป็น / tmp) ซึ่งจะส่งออกตัวแปรสภาพแวดล้อม Virtualenv ไปยังไฟล์ซึ่งคุณจะอ่านในกระบวนการ Python หลักและใส่ใน os.environ

หรือคุณเพียงแค่แยกวิเคราะห์สคริปต์เปิดใช้งานโดยใช้สำหรับบรรทัดในเปิด ("bin / enable") แยกสิ่งต่างๆด้วยตนเองและใส่ใน os.environ เป็นเรื่องยุ่งยาก แต่ไม่เป็นไปไม่ได้


2
คุณหมายถึงอะไรแบบนี้? bitbucket.org/ianb/virtualenv/src/1f9dfb2437f1/…
h3.

2

คำตอบด้านบนใช้ได้กับ Python 2.x เท่านั้น

สำหรับ Python 3.x ให้ใช้สิ่งนี้:

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))

อ้างอิง: ทางเลือกอื่นสำหรับ execfile ใน Python 3 คืออะไร?



1
@randyPen ไฟล์ enable_this.py จะถูกเพิ่มโดยอัตโนมัติเมื่อคุณสร้าง Virtualenv ในไดเร็กทอรีโปรเจ็กต์ของคุณ (เช่น /project/directory/venv/bin/activate_this.py)
TheoreticallyNick

-2

คุณควรสร้างไฟล์ทั้งหมดของคุณvirtualenvในโฟลเดอร์เดียวเช่นvirt .

สมมติว่าชื่อโฟลเดอร์ Virtualenv ของคุณเป็น Virtualenv ถ้าไม่เปลี่ยน

cd
mkdir custom

คัดลอกบรรทัดด้านล่าง ...

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

สร้างไฟล์เชลล์สคริปต์และวางบรรทัดด้านบน ...

touch custom/vhelper
nano custom/vhelper

ให้สิทธิ์ปฏิบัติการกับไฟล์ของคุณ:

sudo chmod +x custom/vhelper

ตอนนี้ส่งออกเส้นทางโฟลเดอร์ที่กำหนดเองเพื่อให้คุณสามารถค้นหาได้ในบรรทัดคำสั่งโดยคลิกที่แท็บ ...

ส่งออก PATH = $ PATH: "$ HOME / กำหนดเอง"

ตอนนี้คุณสามารถใช้งานได้จากทุกที่เพียงพิมพ์คำสั่งด้านล่าง ...

vhelper YOUR_VIRTUAL_ENV_FOLDER_NAME

สมมติว่าเป็น abc แล้ว ...

vhelper abc
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.