删除目录后如何删除所有 pipenv virtualenvs?

How to remove all pipenv virtualenvs when the directory was deleted?

我有一个目录 A/,其中包含一个 Pipfile 和一个由 运行 pipenv install 获得的 Pipfile.lock。所以这个目录在 /home/username/.local/share/virtualenvs/A-....

有对应的 virtualenv

然后我删除这个A/目录。 有没有办法检查所有 pipenv virtualenvs,找到被删除的目录并删除相应的 virtualenvs?

在这种情况下,它应该发现 A/ 已被删除,因此删除 virtualenv:/home/username/.local/share/virtualenvs/A-....

pipenv 没有特殊选项。但是你可以使用这些 bash 脚本(我使用 venvs 目录制作它们 ~/.local/share/virtualenvs/ 所以如果你的 venvs 文件夹不同你应该改变它)

PRINT 无用的 venvs:

for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do proj_path="$(cat $f)"  && [ ! -d "$proj_path" ] && echo ${f//\/.project};  done;

PRINT 不是现有的项目路径 仍然有相应的 venvs:

for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do proj_path="$(cat $f)"  && [ ! -d "$proj_path" ] && echo $proj_path;  done;

打印两者(无用的 venvs 和不存在的项目文件夹):

for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do proj_path="$(cat $f)" && [ ! -d "$proj_path" ] && echo $proj_path "\n"${f//\/.project} "\n";  done;

删除无用的 venvs

for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do proj_path="$(cat $f)" && [ ! -d "$proj_path" ] && rm -rif ${f//\/.project} && echo DELETING ${f//\/.project};  done;

尝试在删除之前打印 venvs!

p.s。如果您的 venv 文件夹不是 ~/.local/share/virtualenvs/,请确保将其更改为您的 venv 路径!

这是一个 bash 脚本,用于基于 .

以交互方式检查和清理废弃的 pipenv 环境
#!/usr/bin/env bash

# Author: TiDu Nguyen
# https://gist.github.com/tidunguyen/0fc018326f33c29e819be7f388360a5b

# get all pipenv environments
allPipenvEnv=$(find ~/.local/share/virtualenvs/*/.project -type f)

# find abandoned environments
abandonedEnv=()
for f in $allPipenvEnv; do
    proj_path="$(cat $f)" && [ ! -d $proj_path ] && abandonedEnv+=($proj_path)
done

# if there is any abandoned environment, prompt for cleaning, else, exit
if [ ${#abandonedEnv[@]} -eq 0 ]; then
    echo "No abandoned environment, hooray"
else
    echo "Found ${#abandonedEnv[@]} abandoned pipenv environment(s):"
    for value in "${abandonedEnv[@]}"; do
        echo $value
    done

    echo -e "\nClean up abandoned pipenv environments?"
    select choice in "Yes" "No"; do
        case $choice in
        Yes)
            for f in $allPipenvEnv; do
                proj_path="$(cat $f)" && [ ! -d $proj_path ] && rm -rif ${f//\/.project/} && echo DELETING ${f//\/.project/}
            done
            echo "Done!"
            break
            ;;
        No)
            break
            ;;
        esac
    done
fi

我基于. You can check it in my repo为此构建了一个函数。 将下面的代码保存到您的个人资料中,e.q。 ~/.bashrc .

# extra pipenv command
pipenv_correspond(){
  local isDefault=true
  local isLS=true
  local isRM=false

  local show_proj_root=true
  local CORRESPOND=""
  declare -a venvs_root_arr=()
  
  local help_book='Usage: pipenv_correspond [OPTION]\n\nOPTION:
  ls,  --list                list all the corresponding projects_root & venvs
  uls, --useless             list all the not existing projects_roots that still have correspondenting venvs
  npr, --no-project-root     hide projects_root
  rm,  --remove              remove all the venvs from command: "ls" or "uls", deafult is use "uls"
  '
  function Show_root(){
    declare -a venvs_arr=()
    declare -i num_venvs=0
    if $show_proj_root; then
      for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do
        proj_root="$(cat $f)" && [ $CORRESPOND -d $proj_root ] && echo "\nproj: $proj_root\nvenv: ${f//\/.project}\n" && venvs_root_arr+=(${f//\/.project}) && num_venvs+=1
      done
    else
      for f in $(find ~/.local/share/virtualenvs/*/.project -type f); do
        proj_root="$(cat $f)" && [ $CORRESPOND -d $proj_root ] && echo "${f//\/.project}\n" && venvs_root_arr+=(${f//\/.project}) && num_venvs+=1
      done
    fi
    echo "Total venvs: $num_venvs"
  }
  if [ "$#" -gt 0 ]; then
    while [ "$#" -gt 0 ]; do
      case  in
        "-h" | "--help" )
          echo $help_book
          return
        ;;
        "ls" | "--list" )
          isDefault=false
          isLS=true
          shift 1
        ;;
        "uls" | "--useless" )
          isDefault=false
          isLS=false
          shift 1
        ;;
        "npr" | "--no-project-root" )
          show_proj_root=false
          shift 1
        ;;
        "rm"  | "--remove" )
          isRM=true
          shift 1 
        ;;
        *)
          echo "\e[31mWrong command keyword!\e[0m" 
          return
        ;;
      esac
    done
  fi
  
  if ! $isLS || ( $isRM && $isDefault ); then
    CORRESPOND="!"
    echo "Useless venvs:"
  else
    echo "Still corresponding venvs:"
  fi

  Show_root venvs_root_arr

  if $isRM; then
    while ! $isDefault && $isLS; do
      printf "\e[33mAre you sure you want to remove all venvs that still existing projects_roots?[y/n] \e[0m"
      read respond
      if [ "$respond" = "n" -o "$respond" = "N" ]; then
        echo "bye~~~"
        return
      elif [ "$respond" != "y" -a "$respond" != "Y" ]; then
        echo "Must type 'y' or 'n'!"
      else
        break
      fi
    done
    echo $venvs_root_arr
    echo "\e[33mWait...\e[0m" 
    for value in ${venvs_root_arr[@]}; do
      echo "remving... $value"
      rm -rf $value
    done
    echo "\e[32mSuccessflly removed all venvs!!\e[0m" 
  fi
}