bash script to activate python venv

50 Views Asked by At

I'm trying to make bash script which should activte my python virtualenv I have it like that:
#!/bin/bash
source /home/xnicram/python/AMW/env/bin/activate

Why it's not working? When I write same in consloe then it;s working

1

There are 1 best solutions below

0
Robert On

When you run the script, the shell starts a new process for it. The script does activate the venv, and then the script process exits, and with that all its settings, like those done by the venv's activation script, are lost. You're back to the parent process, and everything is as before calling the script. When you run it manually on the console, you stay in the same shell (same process), so the settings stick.

To start the venv in a script, you can make a shell function:

function set_python_env() {
    if [[ -d ".pyenv" ]]
    then
        VIRTUAL_ENV_DISABLE_PROMPT=1
        source ".pyenv/bin/activate"
    fi
}

and then call set_python_env in script or shell.

You can even go a step further and hook into the cd command and have it check whether you cd into or out of a pyenv and then activate or deactivate the environment. Put this into e.g., your ~/.bashrc:

# Automatically en/dis-able Python virtual environments:
function cd() {
    builtin cd "$@"
    set_python_env
}

function set_python_env() {
    # Regular / manually created Python virtual environments.
    env=".pyenv"
    if [ -f "poetry.lock" ]
    then
        # If this is a poetry managed project. poetry shell starts a new shell
        # and that doesn't work well for switching back and forth between some
        # environments. Hence manually activate the environment.
        env=$(poetry env info --path)
    fi

    if [[ -z "$VIRTUAL_ENV" ]]
    then
    
        # If env folder is found then activate the virtual env. This only
        # works when cd'ing into the top level Python project directory, not
        # straight into a sub directory. This is probably the common use
        # case as Python depends on the directory hierarchy.
        if [[ -d "$env" ]]
        then
            VIRTUAL_ENV_DISABLE_PROMPT=1
            source "$env/bin/activate"
            
        # else
            # Not a Python project directory..
        fi
    else
        # Check the current folder belong to the current VIRTUAL_ENV. If
        # yes then do nothing, else deactivate, and possibly re-activate if
        # we switched to another venv.
        parentdir="$(dirname "$VIRTUAL_ENV")"
        if [[ "$PWD"/ != "$parentdir"/* ]]
        then
            deactivate
            set_python_env
        fi
    fi
}

set_python_env

Adjust the env variable to your preferred Python environment folder name.