0

I have a code that looks like this:

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 function is written by me and it works if the path provided to it doesn't contain tilde like /home/user/foo. If ~/foo is provided that is going into infinite recursion.

So I found how to expand tilde, but I have very little knowledge of bash, so I can't properly use it in my function.

Can anyone help with that?

Suppose we have following folder structure.

/code/foo/bar/baz
/code/foo/venv/bin/activate
  • if we cd into /code/foo/bar/baz, it should activate venv.
  • if we cd into /code/foo, it should activate venv
  • if we cd out of /code/foo/*, it should deactivate venv.
Vika Marquez
  • 353
  • 1
  • 3
  • 12
user1685095
  • 5,787
  • 9
  • 51
  • 100

1 Answers1

0

Given that the actual goal here is to look for a virtualenv root somewhere above the currently specified directory...

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
}

...used as:

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

Alternately, if you want to find a virtualenv below the current location:

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

Usage is similar. That said, if you wanted to recurse multiple levels rather than only one, I'd strongly suggest using find.

Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • local path_to_search p p=$1 path_to_search=$(expandPath "$p") gives me expandPath:3: bad option: -a dirname: illegal option -- v – user1685095 Dec 18 '15 at 19:22
  • If you don't have `read -a`, your shell isn't bash. Check your shebang, check your interpreter, etc. – Charles Duffy Dec 18 '15 at 19:24
  • Also, it looks like you have a `-v` being passed in `$1`, so your `"$p"` doesn't necessarily include a path at all. – Charles Duffy Dec 18 '15 at 19:25
  • Hm... I'm using zsh indeed. I thought that there would be no difference, but there is. Do you know any portable way of doing that or how to do that in zsh? – user1685095 Dec 18 '15 at 19:27
  • None of this functions do what I want. Please look at my code and understand what it's trying to achieve. – user1685095 Dec 18 '15 at 19:56
  • 1
    @user1685095: I removed `zsh` from the tags since the question explicitly said 'bash' in the title. If you're using `zsh`, then re-retag with [tag:zsh], removing [tag:bash] and use `zsh` in the title and body and not `bash`. They're very different shells; they each go off on their own tangents from the POSIX shell. My impression is that `zsh` has more ways it goes off on its own — but that's a not very well informed impression. – Jonathan Leffler Dec 18 '15 at 20:09
  • @JonathanLeffler okay, I did that. And I tried to use bash. It still doesn't work for me... – user1685095 Dec 18 '15 at 20:14
  • Choose one or the other — you almost certainly won't find a solution that works unchanged for both. – Jonathan Leffler Dec 18 '15 at 20:16
  • okay, I choose zsh, but this functions still not working for me even in bash. http://recordit.co/SOtj502F60 – user1685095 Dec 18 '15 at 20:18