setV: 用于维护 Python 虚拟环境的 Bash 函数

了解 setV,一个轻量级的 Python 虚拟环境管理器,是 virtualenvwrapper 的替代方案。
103 位读者喜欢这个。
Coding on a computer

一年多以来,setV 一直隐藏在我的 bash_scripts 项目中,但现在是时候公开它了。 setV 是我用作 virtualenvwrapper 替代方案的 Bash 函数。 它提供基本功能,使您能够执行以下操作:

  • 默认使用 Python 3
  • 创建一个新的虚拟环境
  • 使用带有 -p (或 --python)的自定义 Python 路径创建一个新的虚拟环境
  • 删除现有的虚拟环境
  • 列出所有现有的虚拟环境
  • 使用 Tab 补全(如果您不记得虚拟环境名称)

安装

要安装 setV,请下载脚本

curl https://gitlab.com/psachin/setV/raw/master/install.sh

查看脚本,然后运行它

sh ./install.sh

当您安装 setV 时,安装脚本会要求您 source ~/.bashrc~/.bash_profile。 请务必这样做。

用法

基本命令是 setv

创建一个虚拟环境

setv --new rango  # setv -n rango

# Or using a custom Python binary path
setv --new --python /opt/python/python3 rango  # setv -n -p /opt/python/python3 rango

激活一个现有的环境

setv VIRTUAL_ENVIRONMENT_NAME

# For example
setv rango

列出所有虚拟环境

setv --list
# or
setv [TAB] [TAB]

删除一个虚拟环境

setv --delete rango

切换到另一个虚拟环境

# Assuming you are in 'rango', switch to 'tango' using
setv tango

Tab 补全

如果您不完全记得虚拟环境的名称,类似 Bash 的 Tab 补全适用于虚拟环境名称。

参与进来

setV 是在 GNU GPLv3 下开源的,欢迎贡献。 要了解更多信息,请访问 setV 的 README 在其 GitLab 仓库中的“Contribute”部分。

setV 脚本

#!/usr/bin/env bash
# setV - A Lightweight Python virtual environment manager.
# Author: Sachin (psachin) <iclcoolster@gmail.com>
# Author's URL: https://psachin.gitlab.io/about
#
# License: GNU GPL v3, See LICENSE file
#
# Configure(Optional):
# Set `SETV_VIRTUAL_DIR_PATH` value to your virtual environments
# directory-path. By default it is set to '~/virtualenvs/'
#
# Usage:
# Manual install: Added below line to your .bashrc or any local rc script():
# ---
# source /path/to/virtual.sh
# ---
#
# Now you can 'activate' the virtual environment by typing
# $ setv <YOUR VIRTUAL ENVIRONMENT NAME>
#
# For example:
# $ setv rango
#
# or type:
# setv [TAB] [TAB]  (to list all virtual envs)
#
# To list all your virtual environments:
# $ setv --list
#
# To create new virtual environment:
# $ setv --new new_virtualenv_name
#
# To delete existing virtual environment:
# $ setv --delete existing_virtualenv_name
#
# To deactivate, type:
# $ deactivate

# Path to virtual environment directory
SETV_VIRTUAL_DIR_PATH="$HOME/virtualenvs/"
# Default python version to use. This decides whether to use `virtualenv` or `python3 -m venv`
SETV_PYTHON_VERSION=3  # Defaults to Python3
SETV_PY_PATH=$(which python${SETV_PYTHON_VERSION})

function _setvcomplete_()
{
    # Bash-autocompletion.
    # This ensures Tab-auto-completions work for virtual environment names.
    local cmd="${1##*/}" # to handle command(s).
                         # Not necessary as such. 'setv' is the only command

    local word=${COMP_WORDS[COMP_CWORD]} # Words thats being completed
    local xpat='${word}'		 # Filter pattern. Include
					 # only words in variable '$names'
    local names=$(ls -l "${SETV_VIRTUAL_DIR_PATH}" | egrep '^d' | awk -F " " '{print $NF}') # Virtual environment names

    COMPREPLY=($(compgen -W "$names" -X "$xpat" -- "$word")) # compgen generates the results
}

function _setv_help_() {
    # Echo help/usage message
    echo "Usage: setv [OPTIONS] [NAME]"
    echo Positional argument:
    echo -e "NAME                       Activate virtual env."
    echo Optional arguments:
    echo -e "-l, --list                 List all Virtual Envs."
    echo -e "-n, --new NAME             Create a new Python Virtual Env."
    echo -e "-d, --delete NAME          Delete existing Python Virtual Env."
    echo -e "-p, --python PATH          Python binary path."
}

function _setv_custom_python_path()
{
    if [ -f "${1}" ];
    then
	if [ "`expr $1 : '.*python\([2,3]\)'`" = "3" ];
	then
	    SETV_PYTHON_VERSION=3
	else
	    SETV_PYTHON_VERSION=2
	fi
	SETV_PY_PATH=${1}
	_setv_create $2
    else
	echo "Error: Path ${1} does not exist!"
    fi
}

function _setv_create()
{
    # Creates new virtual environment if ran with -n|--new flag
    if [ -z ${1} ];
    then
	echo "You need to pass virtual environment name"
	_setv_help_
    else
	echo "Creating new virtual environment with the name: $1"

	if [ ${SETV_PYTHON_VERSION} -eq 3 ];
	then
	    ${SETV_PY_PATH} -m venv ${SETV_VIRTUAL_DIR_PATH}${1}
	else
	    virtualenv -p ${SETV_PY_PATH} ${SETV_VIRTUAL_DIR_PATH}${1}
	fi

	echo "You can now activate the Python virtual environment by typing: setv ${1}"
    fi
}

function _setv_delete()
{
    # Deletes virtual environment if ran with -d|--delete flag
    # TODO: Refactor
    if [ -z ${1} ];
    then
	echo "You need to pass virtual environment name"
	_setv_help_
    else
	if [ -d ${SETV_VIRTUAL_DIR_PATH}${1} ];
	then
	    read -p "Really delete this virtual environment(Y/N)? " yes_no
	    case $yes_no in
		Y|y) rm -rvf ${SETV_VIRTUAL_DIR_PATH}${1};;
		N|n) echo "Leaving the virtual environment as it is.";;
		*) echo "You need to enter either Y/y or N/n"
	    esac
	else
	    echo "Error: No virtual environment found by the name: ${1}"
	fi
    fi
}

function _setv_list()
{
    # Lists all virtual environments if ran with -l|--list flag
    echo -e "List of virtual environments you have under ${SETV_VIRTUAL_DIR_PATH}:\n"
    for virt in $(ls -l "${SETV_VIRTUAL_DIR_PATH}" | egrep '^d' | awk -F " " '{print $NF}')
    do
	echo ${virt}
    done
}

function setv() {
    # Main function
    if [ $# -eq 0 ];
    then
	_setv_help_
    elif [ $# -le 3 ];
    then
	case "${1}" in
	    -n|--new) _setv_create ${2};;
	    -d|--delete) _setv_delete ${2};;
	    -l|--list) _setv_list;;
	    *) if [ -d ${SETV_VIRTUAL_DIR_PATH}${1} ];
	       then
		   # Activate the virtual environment
		   source ${SETV_VIRTUAL_DIR_PATH}${1}/bin/activate
	       else
		   # Else throw an error message
		   echo "Sorry, you don't have any virtual environment with the name: ${1}"
		   _setv_help_
	       fi
	       ;;
	esac
    elif [ $# -le 5 ];
    then
	case "${2}" in
	    -p|--python) _setv_custom_python_path ${3} ${4};;
	    *) _setv_help_;;
	esac
    fi
}

# Calls bash-complete. The compgen command accepts most of the same
# options that complete does but it generates results rather than just
# storing the rules for future use.
complete  -F _setvcomplete_ setv

 

接下来阅读什么
标签
psachin
Sachin 热衷于自由和开源软件。 他是一位狂热的 GNU Emacs 用户,喜欢谈论和撰写关于开源、GNU/Linux、Git 和 Python 的文章。 他之前曾在 OpenStack、ManageIQ/CloudForms 和 Red Hat Insights 工作过。 他还喜欢在业余时间探索 Swift 对象存储。 您可以通过 IRC 联系到他,用户名是 psachin@{Libera.Chat, Freenode, OFTC, gnome}。

3 条评论

有趣的脚本,看起来非常有用。 建议您更改 curl 命令,以下载文件而不是检索并显示到终端。 可能会让那些不太熟悉 shell 命令的人感到困惑,并想知道为什么他们无法安装它。

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.