シェル関数(deactivate()
Python virtualenvで定義された関数)があり、実行前後にいくつかのステートメントを挿入してパッチを適用したいと思います。私の目標は、deactivate()
既存の関数の機能を実行し、はるかに多くの作業を実行する新しい関数を作成することです。これを行う方法はありますか?
元の関数はさまざまな場所(個々のvirtualenv)で動的に定義されているため、すべてのソースでそれらを変更することは魅力的なオプションではありません。
答え1
十分であれば、関数より優先順位の高い無効化エイリアスを生成できます。以前はコマンドを実行できますが、後で実行するのは簡単ではないからです。
alias deactivate='before; deactivate'
あるいは、単純に(より良い)より単純な名前で関数を作成します。
deact(){ [[ $somevar == true ]] && deactivate
[[ $othervar == admin ]] && sudo deactivate
}
または実装したいものは何でも。はい、定義されている場合にのみ実行されます。これは用語に代わるものではなく、deactivate
他のユーザーには使用できません。
唯一の方法は、名前がdeactivate
エイリアスまたは関数よりも優先順位の低い実行可能プログラムを作成することです。どちらも定義しないでください。
答え2
シェルがある場合、または組み込み関数を利用できる場合は、関数bash
のソースコードが表示されますzsh
。ksh93
typeset -f
# usage patch_func funcname before after
function patch_func {
typeset nl=$'\n' lb={ src=`typeset -f "$1"` before=$2 after=$3
src="${src/$lb/$lb$nl $before$nl}"
src="${src%\}*}$nl $after$nl}"
eval "$src"
}
例:
$ deactivate(){ echo -n "{$0}"; for i; do echo -n " {$i}"; done; echo; }
$ patch_func deactivate 'echo before' 'echo after'
$ typeset -f deactivate
deactivate ()
{
echo before;
echo -n "{$0}";
for i in "$@";
do
echo -n " {$i}";
done;
echo;
echo after
}
もちろん、これは非常に脆弱です。
答え3
この答えは使用法に直接適用されませんが、virtualenv
使用法はどうですかvirtualenvwrapper
?基本的にvirtualenv
ステロイドのための環境管理です。インストール後、次の追加のコマンドセットが提供されます。
workon
引数なしで呼び出すときに使用可能なすべての環境を一覧表示し、env名を引数として使用して呼び出すときにenvを有効にしworkon myenv
ますmyenv
。mkvirtualenv myenv
新しい環境を作成しますmyenv
。rmvirtualenv myenv
削除してください。
しかし、それ以上があります。virtualenvwrapper
独自の envs カスタムロジックを実装できる有用なフックセットが定義されています。たとえば、次のようになります。
premkvirtualenv
環境が作成されたがまだアクティブでない場合に実行されます。postmkvirtualenv
envが作成されアクティブになったときに実行されます。preactivate
env アクティベーションがトリガされると実行されます。postactivate
envが有効になると実行されます。predeactivate
環境の無効化がトリガされると実行されます。postdeactivate
env が無効の場合に実行されます。
もっとあります。たとえば、新しい環境にフックがインストールされてpostmkvirtualenv
います。ipython
$ cat $VIRTUALENVWRAPPER_HOOK_DIR/postmkvirtualenv
#!/bin/bash
# This hook is sourced after a new virtualenv is activated.
env=$(basename "$VIRTUAL_ENV")
logger -s -t "($env)" "installing ipython ..."
"$VIRTUAL_ENV/bin/pip" install ipython --quiet
envを無効にするための追加ロジックを定義するには、カスタムbashスクリプトを作成し、その内容を$VIRTUALENVWRAPPER_HOOK_DIR/predeactivate
(envがまだアクティブな状態でジョブを実行する必要がある場合)または$VIRTUALENVWRAPPER_HOOK_DIR/postdeactivate
(envを無効にする必要がある場合はカスタムコードの実行)に配置する必要があります。します。
参考までに:virtualenvwrapper
文書。
フックの完全なリストについては、以下を参照してください。ユーザー固有のカスタマイズ。