【问题标题】:What goes under the hood of `mkvirtualenv` command?`mkvirtualenv` 命令的底层是什么?
【发布时间】:2012-05-03 17:40:31
【问题描述】:

我很好奇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.bash_profile 文件中获取了 virtualenvwrapper.sh。

深入了解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"
}

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

【问题讨论】:

    标签: virtualenv virtualenvwrapper


    【解决方案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"
    )
    

    $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
    

    谜团解开了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-04
      • 1970-01-01
      • 2018-11-16
      • 1970-01-01
      • 2017-07-26
      • 2014-11-20
      • 2014-04-15
      • 2017-12-02
      相关资源
      最近更新 更多