web-dev-qa-db-ja.com

シェル関数は、virtualenv内で実行されているかどうかをどのように知ることができますか?

bash関数は、Python virtualenv内で実行されているかどうかをどのようにテストする必要がありますか?

頭に浮かぶ2つのアプローチは次のとおりです。

[[ "$(type -t deactivate)" != function ]]; INVENV=$?

または

[[ "x$(which python)" != "x$VIRTUAL_ENV/bin/python" ]]; INVENV=$?

(注:virtualenv内にいる場合は$INVENVを1にし、それ以外の場合は0にしたいので、上記の後方視テストが強制されます。)

ハッキーでないものはありますか?

27
kjo

実際、私はちょうど同様の質問を見つけました。そこから、これに対する答えを簡単に導き出すことができます。

Python:virtualenv内で実行されているかどうかを判断します

たとえば、シェルスクリプトは次のようなものを使用できます

python -c 'import sys; print (sys.real_prefix)' 2>/dev/null && INVENV=1 || INVENV=0

(このソリューションをPython 3も)で機能させる方法を示してくれたChristian Longに感謝します。)

編集:これはより直接的な(したがってより明確でよりクリーンな)解決策です(JuanPabloのコメントからヒントを得ています):

INVENV=$(python -c 'import sys; print ("1" if hasattr(sys, "real_prefix") else "0")')
15
kjo
if [[ "$VIRTUAL_ENV" != "" ]]
then
  INVENV=1
else
  INVENV=0
fi
// or shorter if you like:
[[ "$VIRTUAL_ENV" == "" ]]; INVENV=$?

[〜#〜] edit [〜#〜]:@ ThiefMasterがコメントで言及しているように、特定の条件(たとえば、新しいシェルを開始するとき–おそらくtmuxまたはscreen –アクティブなvirtualenv内から)このチェックは失敗する可能性があります(ただし、virtualenv内から新しいシェルを開始すると、他の問題も発生する可能性があるため、お勧めしません)。

32
robertklep

Virtualenvwrappersを使用する場合、INVENVを設定できる実行される事前/事後スクリプトがあります。

または、私が行うことは、次のことを.bashrcに入れ、作業ディレクトリ(Djangoの場合)に.venvというファイルを作成して、ディレクトリにcdしたときに仮想環境が自動的にロードされるようにします。

export PREVPWD=`pwd`
export PREVENV_PATH=

handle_virtualenv(){
    if [ "$PWD" != "$PREVPWD" ]; then
        PREVPWD="$PWD";
        if [ -n "$PREVENV_PATH" ]; then
            if [ "`echo "$PWD" | grep -c $PREVENV_PATH`" = "0"  ]; then
                deactivate
                unalias python 2> /dev/null
                PREVENV_PATH=
            fi
        fi

        # activate virtualenv dynamically
        if [ -e "$PWD/.venv" ] && [ "$PWD" != "$PREVENV_PATH" ]; then
            PREVENV_PATH="$PWD"
            workon `basename $PWD`
            if [ -e "manage.py" ]; then
                alias python='python manage.py Shell_plus'
            fi
        fi
    fi
}

export Prompt_COMMAND=handle_virtualenv
1
Kurt