Bash 스크립트에서 virtualenv 활성화를 소싱하는 방법


98

Python virtualenv를 활성화하기 위해 Bash 스크립트를 어떻게 생성합니까?

다음과 같은 디렉토리 구조가 있습니다.

.env
    bin
        activate
        ...other virtualenv files...
src
    shell.sh
    ...my code...

다음과 같은 방법으로 내 virtualenv를 활성화 할 수 있습니다.

user@localhost:src$ . ../.env/bin/activate
(.env)user@localhost:src$

그러나 Bash 스크립트에서 동일한 작업을 수행하면 아무 작업도 수행되지 않습니다.

user@localhost:src$ cat shell.sh
#!/bin/bash
. ../.env/bin/activate
user@localhost:src$ ./shell.sh
user@localhost:src$ 

내가 뭘 잘못하고 있죠?


6
셸 스크립트를 실행하면 실제로 새 셸이 생성됩니다. 사용의 요점은 source현재 쉘에서 무언가를 변경하는 것입니다. 전체 경로를 사용하여 virtualenv의 파이썬을 사용할 수 있습니다 ./env/bin/python.
Pablo Navarro

@NgureNyaga, 아니, 그 질문은 내 질문과 같지 않습니다. 그들은 임의의 위치에서 소스를 얻는 방법을 묻습니다. 나는 이것을하는 방법을 이미 알고있다. 커스텀 bash 스크립트 내에서 소스를 사용하고 소스를 유지하는 방법을 묻습니다.
Cerin

답변:


79

소싱 할 때 활성 셸에 활성화 스크립트를로드합니다.

스크립트에서 수행하면 스크립트가 완료되고 활성화되지 않은 원래 셸로 돌아갈 때 종료되는 셸로로드합니다.

가장 좋은 방법은 함수에서 수행하는 것입니다.

activate () {
  . ../.env/bin/activate
}

또는 별칭

alias activate=". ../.env/bin/activate"

도움이 되었기를 바랍니다.


\ 튜토리얼> \ ENV \ 스크립트 \ 활성화합니다. C 창문
max4ever

6
나는 내가 소스를 할 때 무슨 일이 일어 났는지 전혀 몰랐습니다. 이것은 내 bash 스크립팅을 크게 변경했습니다. 감사합니다!
Robert Townley

1
당신의 별칭 아이디어는 나에게도 잘 작동했습니다. 참고 사항 : .zshrc 스크립트 (또는 bash 사용자의 경우 .bashrc)에이 파일 (별칭 abcdef = "source ... / bin / activate")을 넣어야 작동합니다.
shahins

기본 폴더 이름을 사용하는 virtualenv가있는 경우 이것은 좋은 솔루션입니다. 폴더에 두 개 이상의 저장소가있어서 virtualenvs가 엉망이되었습니다. 지금이 기본값으로 전환했습니다.
3manuek

3
저는 bash 등에 익숙하지 않습니다.이 예제를 확장하여 전체 스크립트를 표시 할 수 있습니까?
AljoSt

57

source를 사용하여 bash 스크립트를 호출해야합니다.

다음은 예입니다.

#!/bin/bash
# Let's call this script venv.sh
source "<absolute_path_recommended_here>/.env/bin/activate"

쉘에서 다음과 같이 호출하십시오.

> source venv.sh

또는 @outmind가 제안한대로 : (zsh에서는 작동하지 않음)

> . venv.sh

거기에 쉘 표시가 프롬프트에 배치됩니다.


2
또는 그냥 ". venv.sh"
outmind

아니, 난 노력할 문제, 이것은 source "/home/surest/Desktop/testservers/TEST_VENV/venv3/bin/activate"생산 :/home/surest/Desktop/testservers/TEST_VENV/py3.sh: 10: /home/surest/Desktop/testservers/TEST_VENV/py3.sh: source: not found

which source쉘 프롬프트에서 입력해도 아무것도 얻지 source venv3/bin/activate못하지만 예상대로 수행하고 venv를 엽니 다. ...

이것이 작동하지만 source ./env/bin/activate(동일한 #!/bin/bash접두사 사용) 작동하지 않는 이유는 무엇 입니까? 따옴표를 사용하는 것과 사용하지 않는 것의 차이점은 무엇입니까?
blacksite

따옴표없이 스크립트 내에서 소스를 사용하는 데 문제가 없습니다. source ./env/bin/activate이것이 바로 실행중인 경로 와 관련이 있기 때문에 문제가 있습니까? 스크립트 내에서 디렉토리를 변경하면 상대적으로 갈 수 있습니다.
Flavio Garcia

13

쉘 프롬프트에 "(.env)"접두어를 추가하지는 않지만이 스크립트가 예상대로 작동한다는 것을 알았습니다.

#!/bin/bash
script_dir=`dirname $0`
cd $script_dir
/bin/bash -c ". ../.env/bin/activate; exec /bin/bash -i"

예 :

user@localhost:~/src$ which pip
/usr/local/bin/pip
user@localhost:~/src$ which python
/usr/bin/python
user@localhost:~/src$ ./shell
user@localhost:~/src$ which pip
~/.env/bin/pip
user@localhost:~/src$ which python
~/.env/bin/python
user@localhost:~/src$ exit
exit

5
기술적으로 서브 쉘을 생성합니다. 반드시 문제는 아니지만 OP에 대해 철자를 써야합니다.
richo

작동했지만 이전에 "활성화"파일에 대한 권한을 부여해야했습니다.
Adrian Lopez

1
이것은 2019 년에 작동합니다! macos에서 방금 변경해야 /bin/bash했습니다/usr/bin/env bash
valem

2020 년 Ubuntu 18.04 AWS EC2에서 작동합니다. 동일한 로직을 사용하여 비활성화하려면 어떻게해야합니까?
CSF 주니어

당신 deactivate과 함께 서브 쉘에서 exit또는 Ctrl + d를
알렉스 로슈

10

소싱은 현재 셸에서 셸 명령을 실행합니다. 위와 같이 스크립트 내부를 소싱하면 해당 스크립트의 환경에 영향을 주지만 스크립트가 종료되면 환경 변경이 취소되어 효과적으로 범위를 벗어났습니다.

virtualenv에서 쉘 명령을 실행하려는 경우 activate 스크립트를 소싱 한 후 스크립트에서 수행 할 수 있습니다. virtualenv 내부의 셸과 상호 작용하려는 경우 환경을 상속하는 스크립트 내부에 하위 셸을 생성 할 수 있습니다.


2

자주 사용하는 스크립트입니다. 다음으로 실행$ source script_name

#!/bin/bash -x
PWD=`pwd`
/usr/local/bin/virtualenv --python=python3 venv
echo $PWD
activate () {
    . $PWD/venv/bin/activate
}

activate

1

bash 스크립트는 무엇을 위해 소싱합니까?

  1. 여러 virtualenv 사이를 전환하거나 하나의 virtualenv를 빠르게 입력하려는 경우 시도해 보셨습니까 virtualenvwrapper? workon venv, 등과 같은 많은 유틸리티를 제공합니다 mkvirtualenv venv.

  2. 특정 virtualenv에서 python 스크립트를 실행하는 경우을 사용 /path/to/venv/bin/python script.py하여 실행하십시오.


실제로 workon ...bash 스크립트에서 호출 하고 싶습니다 . (나중에 시작할 때마다 추가 작업을 실행하고 싶기 때문입니다.) 그래도 작동하도록 할 방법을 찾을 수 없습니다.
Daniel B.

1

사용을 더 잘 포함하기 위해 서브 쉘을 사용하여이 작업을 수행 할 수도 있습니다. 실제 예는 다음과 같습니다.

#!/bin/bash

commandA --args

# Run commandB in a subshell and collect its output in $VAR
# NOTE
#  - PATH is only modified as an example
#  - output beyond a single value may not be captured without quoting
#  - it is important to discard (or separate) virtualenv activation stdout
#    if the stdout of commandB is to be captured
#
VAR=$(
    PATH="/opt/bin/foo:$PATH"
    . /path/to/activate > /dev/null  # activate virtualenv
    commandB  # tool from /opt/bin/ which requires virtualenv
)

# Use the output from commandB later
commandC "$VAR"

이 스타일은 특히 다음과 같은 경우에 유용합니다.

  • 다른 버전 commandA또는 commandC아래에 존재/opt/bin
  • commandB시스템에 존재 PATH하거나 매우 일반적입니다
  • 이러한 명령은 virtualenv에서 실패합니다.
  • 다양한 가상 환경이 필요합니다.

큰 따옴표를 잊지 마세요. 그렇지 않으면 $(...)출력에 포함 된 공백과 탭이 누락됩니다.
Eric

"${VAR}""$VAR"큰 따옴표가 실제로 더 강력하기 때문에 쉘 변수 주위에 중괄호가 필요하지 않은 것과 완전히 동일합니다 . 예외는 예를 들어 수정자를 사용하는 경우입니다"${VAR:-default_value}"
Eric

PATH=$PATH:/opt/bin공백과 탭이있는 경로를 처리하려면 적절한 인용이 필요합니다.
Eric

@Eric 감사 edit합니다. 게시물 아래 의 버튼을 사용하여 변경 사항을 제안 할 수 있습니다! 또한 안전을 위해 필요한 경우가 많고 중요하지만 고의로 IFS문자를 추가하는 사람 PATH은 테러리스트라는 사실을 알고 있어야합니다 .
ti7

0

한 줄에 여러 명령을 사용해야합니다. 예를 들면 :

os.system(". Projects/virenv/bin/activate && python Projects/virenv/django-project/manage.py runserver")

한 줄에서 가상 환경을 활성화하면 다른 명령 줄을 잊어 버리고 한 줄에 여러 명령을 사용하여이를 방지 할 수 있습니다. 그것은 나를 위해 일했습니다 :)


0

venv를 배울 때 활성화 방법을 알려주는 스크립트를 만들었습니다.

#!/bin/sh
# init_venv.sh
if [ -d "./bin" ];then
  echo "[info] Ctrl+d to deactivate"
  bash -c ". bin/activate; exec /usr/bin/env bash --rcfile <(echo 'PS1=\"(venv)\${PS1}\"') -i"
fi

이것은 프롬프트를 변경한다는 장점이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.