Мне любопытно, что происходит под капотом команды 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 и доступна в моем терминале, потому что я получил virtualenvwrapper.sh в своих файлах .bashrc
или .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
?