workon <envname>
在CMD中可以正常工作,但在Windows PowerShell中不行。
在Windows PowerShell中,我需要运行Scripts\activate.ps1
,然后才能在提示符前获取envname。
请问如何让workon命令在PowerShell中正常工作呢?
workon <envname>
在CMD中可以正常工作,但在Windows PowerShell中不行。
在Windows PowerShell中,我需要运行Scripts\activate.ps1
,然后才能在提示符前获取envname。
请问如何让workon命令在PowerShell中正常工作呢?
workon
是一个批处理脚本。如果你从PowerShell运行它,它会在一个新的CMD子进程中启动,在那里执行它的任务,然后退出并返回到PowerShell提示符。由于子进程不能修改其父进程,当你返回到PowerShell时,所有由workon.bat
所做的修改都会丢失。
你基本上有两个选择:
用PowerShell重写workon.bat
(以及其他它调用的批处理脚本)。
在不退出CMD子进程的情况下运行workon.bat
:
& cmd /k workon <envname>
如果您只想要一个可以直接从PowerShell调用的workon
快捷方式,您可以将该命令行包装在一个函数中,并将函数定义放入您的PowerShell配置文件中:
如果您只想从PowerShell直接调用workon
,可以将该命令行包装在一个函数中,并将函数定义放入您的PowerShell个人资料中:
function workon($environment) {
& cmd /k workon.bat $environment
}
在此处使用带扩展名的脚本名称,以避免无限递归。
Ansgar Wiechers的回答在技术上是可行的,但它使用了cmd
,这意味着你基本上是在PowerShell中使用命令提示符,失去了PowerShell提供的额外功能。你可以修改上面的函数如下:
function workon ($env) {
& .\Envs\$env\Scripts\activate.ps1
}
ls
)。WORKON_HOME
环境变量,请参见下文。WORKON_HOME
环境变量(您应该这样做!),则可以改为使用:function workon ($env) {
& $env:WORKON_HOME\$env\Scripts\activate.ps1
}
只需在PowerShell上键入“CMD”,它会打开命令提示符,然后使用“workon”命令。
有一个更简单的解决方案!只需转到您的Python脚本文件夹,其中存在workon.bat
文件,并创建一个名为workon.ps1
的新文件,并将以下行添加到其中
iex ("~\Envs\" + $args[0] + "\Scripts\activate.ps1")
ps1
将在powershell中执行,而bat
将在cmd中执行。workon.ps
和cdproject
。
workon.ps1
:if (-not (Test-Path env:WORKON_HOME))
{
$WORKON_HOME = '~\Envs'
} else {
$WORKON_HOME = ($env:WORKON_HOME).Replace('"','')
}
if (-not (Test-Path env:VIRTUALENVWRAPPER_PROJECT_FILENAME)) {
$VIRTUALENVWRAPPER_PROJECT_FILENAME = '.project'
} else {
$VIRTUALENVWRAPPER_PROJECT_FILENAME = ($env:VIRTUALENVWRAPPER_PROJECT_FILENAME).Replace('"','')
}
if ($args.length -eq 0) {
echo "Pass a name to activate one of the following virtualenvs:"
echo ==============================================================================
(Get-ChildItem -Path $WORKON_HOME).Name
return
}
$VENV = $args[0]
if (!(Test-Path -Path ("$($WORKON_HOME)\$($VENV)"))) {
echo ("virtualenv $($VENV) does not exist")
echo "Create it with 'mkvirtualenv $($VENV)'"
return
}
if (!(Test-Path -Path ("$($WORKON_HOME)\$($VENV)\Scripts\activate.ps1") )) {
echo "$($WORKON_HOME)$($VENV)"
echo "doesn't contain a virtualenv (yet)."
echo "Create it with 'mkvirtualenv $($VENV)'"
return
}
iex ("$($WORKON_HOME)\$($VENV)\Scripts\activate.ps1")
if (Test-Path -Path ("$($WORKON_HOME)\$($VENV)\$($VIRTUALENVWRAPPER_PROJECT_FILENAME)")) {
iex "cdproject"
}
cdproject.ps1
:
function Show-Usage {
echo ""
echo "switches to the project dir of the activated virtualenv"
}
if (-not (Test-Path env:VIRTUAL_ENV)) {
echo ""
echo "a virtualenv must be activated"
Show-Usage
return
}
if (-not (Test-Path env:VIRTUALENVWRAPPER_PROJECT_FILENAME)) {
$VIRTUALENVWRAPPER_PROJECT_FILENAME = '.project'
} else {
$VIRTUALENVWRAPPER_PROJECT_FILENAME = ($env:VIRTUALENVWRAPPER_PROJECT_FILENAME).Replace('"','')
}
if (-not (Test-Path "$($env:VIRTUAL_ENV)\$($VIRTUALENVWRAPPER_PROJECT_FILENAME)")) {
echo ""
echo "No project directory found for current virtualenv"
Show-Usage
return
}
$ENVPRJDIR = Get-Content "$($env:VIRTUAL_ENV)\$($VIRTUALENVWRAPPER_PROJECT_FILENAME)" -First 1
# If path extracted from file contains env variables, the system will not find the path.
# TODO: Add this functionality
cd $ENVPRJDIR
& cmd /k workon <envname>
比你提出的要简单得多。 - ron_gInvoke-Expression
的东西(比如你的代码)都是默认错误的。 - Ansgar Wiechers我在Windows10的powershell中使用virtualenvwrapper时遇到了同样的问题。我喜欢@Erock的答案,但是它覆盖了workon
,这样运行workon
而不带参数会抛出错误,而不是显示可用环境。以下是我的解决方案。
function workon ($env) {
if ($env) {
& $env:WORKON_HOME\$env\Scripts\activate.ps1
} else {
Write-Host "Pass a name to activate one of the following virtualenvs:"
Write-Host" ================================================================"
Get-ChildItem $env:WORKON_HOME -Name
}
}
我也遇到了类似的问题,但是通过按照上面的步骤解决了它。
在这里列出来:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
安装:
{ pip install virtualenvwrapper-win }
function workon ($env) {
& .\Envs\$env\Scripts\activate.ps1
}
创建虚拟环境:
{ workon venv }
或任何其他名称 激活中:
{ . venv\scripts\activate }
查看已创建的虚拟环境列表:
{ workon }
停用:
{ deactivate }