在zsh中自动化virtualenv激活/停用

时间:2015-12-18 19:12:34

标签: linux shell unix zsh

我的代码如下:

has_venv_in_path() {
    unsetopt nomatch 2>/dev/null
    local path_to_search
    path_to_search=$1
    echo "searching in $path_to_search"
    if [[ ${path_to_search} = "/" ]]; then
        echo "no"
    fi

    ls ${path_to_search}/*/bin/activate > /dev/null 2> /dev/null
    if [ "$?" = '0' ]; then
        echo "yes"
    else
        has_venv_in_path $(dirname "$path_to_search")
    fi
}

has_venv_in_path函数由我编写,如果提供给它的路径不包含像/home/user/foo这样的波浪号,它就可以工作。如果提供的~/foo将进入无限递归。

所以我找到了如何扩展代字号,但我对bash知之甚少,所以我无法在我的函数中正确使用它。

任何人都可以帮忙吗?

假设我们有以下文件夹结构。

/code/foo/bar/baz
/code/foo/venv/bin/activate
  • 如果我们cd进入/code/foo/bar/baz,则应激活venv。
  • 如果我们cd进入/code/foo,则应激活venv
  • 如果我们cd /code/foo/*,则应停用venv。

1 个答案:

答案 0 :(得分:0)

鉴于此处的实际目标是在当前指定目录之上的某处寻找virtualenv根...

find_venv_above() {
  local dir=${1:-$PWD}
  while [[ $dir = /*/* ]]; do
    [[ -e "$dir/bin/activate" ]] && {
      printf '%s\n' "$dir"
      return 0
    }
    dir=${dir%/*}
  done
  return 1
}

...用作:

if venv_root=$(find_venv_above); then
  echo "Currently in a virtualenv rooted at $venv_root"
fi

或者,如果您想在下面找到virtualenv 当前位置:

find_venv() {
  for option in "${1:-$PWD}"/*/bin/activate; do
    [[ -x "$option" ]] && {
      printf '%s\n' "${option%/bin/activate}"
      return 0
    }
  done
  return 1
}

用法类似。也就是说,如果你想要递增多个级别而不是只有一级,我强烈建议使用find