Bash 기능 패치

Bash 기능 패치

쉘 함수( deactivate()Python virtualenv에 의해 정의된 함수)가 있고 실행 전후에 몇 가지 명령문을 삽입하여 패치하고 싶습니다. 내 목표는 deactivate()기존 함수의 기능을 수행하고 훨씬 더 많은 작업을 수행하는 새로운 함수를 만드는 것입니다 . 이를 수행할 수 있는 방법이 있습니까?

원래 함수는 다양한 위치(개별 virtualenv)에서 동적으로 정의되므로 모든 소스에서 이를 수정하는 것은 매력적인 옵션이 아닙니다.

답변1

충분하다면 함수보다 우선순위가 높은 비활성화 별칭을 생성할 수 있습니다. 이전에 명령을 실행할 수 있지만 나중에 실행하기가 쉽지 않기 때문입니다.

alias deactivate='before; deactivate'

아니면 간단하게 (더 나은) 더 간단한 이름으로 함수를 만듭니다.

deact(){ [[ $somevar == true ]] && deactivate
         [[ $othervar == admin ]] && sudo deactivate
       }

또는 구현하고 싶은 것이 무엇이든. 예, 정의된 경우에만 실행됩니다. 이는 용어를 대체하지 않으며 deactivate다른 사용자가 사용할 수 없습니다.

유일한 방법은 이름이 deactivate별칭이나 함수보다 우선순위가 낮은 실행 가능한 프로그램을 만드는 것입니다. 둘 다 정의되지 않아야 합니다.

답변2

쉘이 이거나 내장 함수를 활용할 수 있는 경우 bash함수 의 소스 코드가 표시 됩니다 zsh.ksh93typeset -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환경이 생성되었지만 아직 활성화되지 않은 경우 실행됩니다.
  • postmkvirtualenvenv가 생성되고 활성화될 때 실행됩니다.
  • preactivateenv 활성화가 트리거될 때 실행됩니다.
  • postactivateenv가 활성화되면 실행됩니다.
  • predeactivate환경 비활성화가 트리거될 때 실행됩니다.
  • postdeactivateenv가 비활성화되면 실행됩니다.

더 많은 것이 있습니다. 예를 들어, 새 환경에 후크가 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문서.

후크의 전체 목록은 다음을 참조하세요.사용자별 맞춤형.

관련 정보