virtualenv - `mkvirtualenv` 命令的背后是什么?

标签 virtualenv virtualenvwrapper

我很好奇 mkvirtualenv 引擎盖下发生了什么命令,所以我试图了解它如何调用 virtualenv .

最简单的结果是找出安装后virtualenv程序所在的位置以及安装后mkvirtualenv程序所在的位置。所以:-

Calvins-MacBook-Pro.local ttys006 Mon Apr 23 12:31:07 |~|
calvin$ which mkvirtualenv
Calvins-MacBook-Pro.local ttys006 Mon Apr 23 12:31:10 |~|
calvin$ which virtualenv
/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv

所以我在这里看到的奇怪的事情是 which mkvirtualenv没有给出任何结果。为什么?

进一步挖掘,安装后在 virtualenvwrapper 目录中,我只看到 3 个 python 文件:-
Calvins-MacBook-Pro.local ttys004 Mon Apr 23 12:28:05 |/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/virtualenvwrapper|
calvin$ ls -la
total 88
drwxr-xr-x   8 root  wheel    272 Apr 13 15:07 .
drwxr-xr-x  29 root  wheel    986 Apr 15 00:55 ..
-rw-r--r--   1 root  wheel   5292 Apr 13 15:05 hook_loader.py
-rw-r--r--   1 root  wheel   4810 Apr 13 15:07 hook_loader.pyc
-rw-r--r--   1 root  wheel   1390 Apr 13 15:05 project.py
-rw-r--r--   1 root  wheel   2615 Apr 13 15:07 project.pyc
-rw-r--r--   1 root  wheel   7381 Apr 13 15:05 user_scripts.py
-rw-r--r--   1 root  wheel  11472 Apr 13 15:07 user_scripts.pyc

我想这是唯一的原因 mkvirtualenv现在在我的终端中可用是因为我添加了 source/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenvwrapper.sh .所以回答我之前问的问题,这仅仅是因为mkvirtualenv表示为 bash 函数并且在我的终端中可用,因为我在 .bashrc 中获取了 virtualenvwrapper.sh或 .bash_profile文件。

深挖virtualenvwrapper.sh脚本,我明白了
# Create a new environment, in the WORKON_HOME.
#
# Usage: mkvirtualenv [options] ENVNAME
# (where the options are passed directly to virtualenv)
#
function mkvirtualenv {
    typeset -a in_args
    typeset -a out_args
    typeset -i i
    typeset tst
    typeset a
    typeset envname
    typeset requirements
    typeset packages

    in_args=( "$@" )

    if [ -n "$ZSH_VERSION" ]
    then
        i=1
        tst="-le"
    else
        i=0
        tst="-lt"
    fi
    while [ $i $tst $# ]
    do
        a="${in_args[$i]}"
        # echo "arg $i : $a"
        case "$a" in
            -a)
                i=$(( $i + 1 ));
                project="${in_args[$i]}";;
            -h)
                mkvirtualenv_help;
                return;;
            -i)
                i=$(( $i + 1 ));
                packages="$packages ${in_args[$i]}";;
            -r)
                i=$(( $i + 1 ));
                requirements="${in_args[$i]}";;
            *)
                if [ ${#out_args} -gt 0 ]
                then
                    out_args=( "${out_args[@]-}" "$a" )
                else
                    out_args=( "$a" )
                fi;;
        esac
        i=$(( $i + 1 ))
    done

    set -- "${out_args[@]}"

    eval "envname=\$$#"
    virtualenvwrapper_verify_workon_home || return 1
    virtualenvwrapper_verify_virtualenv || return 1
    (
        [ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
        \cd "$WORKON_HOME" &&
        "$VIRTUALENVWRAPPER_VIRTUALENV" $VIRTUALENVWRAPPER_VIRTUALENV_ARGS "$@" &&
        [ -d "$WORKON_HOME/$envname" ] && \
            virtualenvwrapper_run_hook "pre_mkvirtualenv" "$envname"
    )
    typeset RC=$?
    [ $RC -ne 0 ] && return $RC

    # If they passed a help option or got an error from virtualenv,
    # the environment won't exist.  Use that to tell whether
    # we should switch to the environment and run the hook.
    [ ! -d "$WORKON_HOME/$envname" ] && return 0

    # If they gave us a project directory, set it up now
    # so the activate hooks can find it.
    if [ ! -z "$project" ]
    then
        setvirtualenvproject "$WORKON_HOME/$envname" "$project"
    fi

    # Now activate the new environment
    workon "$envname"

    if [ ! -z "$requirements" ]
    then
        pip install -r "$requirements"
    fi

    for a in $packages
    do
        pip install $a
    done

    virtualenvwrapper_run_hook "post_mkvirtualenv"
}

这是我还不明白的地方 - 我似乎没有看到任何对 virtualenv 的直接引用。在这个 bash 函数中。那么这个 bash 函数究竟是如何运作的mkvirtualenv将参数从命令行(例如 mkvirtualenv -p python2.7 --no-site-packages mynewproject )传递给 python virtualenv程序?

最佳答案

所以这是行得通的。

(
    [ -n "$ZSH_VERSION" ] && setopt SH_WORD_SPLIT
    \cd "$WORKON_HOME" &&
    "$VIRTUALENVWRAPPER_VIRTUALENV" $VIRTUALENVWRAPPER_VIRTUALENV_ARGS "$@" &&
    [ -d "$WORKON_HOME/$envname" ] && \
        virtualenvwrapper_run_hook "pre_mkvirtualenv" "$envname"
)
$VIRTUALENVWRAPPER_VIRTUALENV其实就是当前virtualenv所在的位置程序驻留。

在终端,
Calvins-MacBook-Pro.local ttys004 Mon Apr 23 13:24:14 |~|
calvin$ which $VIRTUALENVWRAPPER_VIRTUALENV
/opt/local/library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv

谜底解决了。

关于virtualenv - `mkvirtualenv` 命令的背后是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10274985/

相关文章:

python - Django 从apache 获取环境变量

python - 如何在virtualenv中使用Pacman安装的NumPy?

python - 打包一个使用多个python版本的项目

python - 从脚本中获取 virtualenv 的 bin 文件夹路径

python - 未找到 Virtualenv 命令

python - virtualenvwrapper/Ubuntu 16.04 的错误

python - 在 MacOS 上为 Python 3.6 初始化 virtualenvwrapper

全局安装的 Python 包,但不在 virtualenv (PyGTK) 中

tkinter - python virtualenv空闲和tkinter问题

python - 将全局包导入到我创建的虚拟环境中的选项?