2016-08-14 359 views
2

我已經安裝了virtualenvwrapper贏,當我嘗試這個命令workon命令不會在Windows PowerShell中工作,以激活的virtualenv

workon <envname> 

在CMD它的工作原理,但不是在Windows PowerShell中。

在Windows PowerShell中,我必須做Scripts\activate.ps1,然後在提示符前獲取envname。

您能否讓我知道如何讓workon命令在PowerShell中工作?

回答

5

workon是批處理腳本。如果你從PowerShell運行它,它會在一個新的CMD子進程中啓動,在那裏做它的事情,然後退出並返回到PowerShell提示符。由於子進程無法修改其父進程,所以當您返回到PowerShell時,將丟失workon.bat所做的所有修改。

你基本上有兩種選擇:

  • 重寫workon.bat(和它調用其他批處理腳本)在PowerShell中。

  • 運行workon.bat,而不脫離CMD子進程退出:

    & cmd /k workon <envname> 
    

    如果你只是想要一個快捷方式workon,你可以從PowerShell中直接調用你可以用該命令行中的函數,並把函數定義插入到PowerShell配置文件中:

    function workon($environment) { 
        & cmd /k workon.bat $environment 
    } 
    

    在此處使用帶擴展名的scriptname以避免無限遞歸。

+0

這個功能是方便的,謝謝! – Patrick

+0

第二種選擇是不正確的,因爲它不再使用PowerShell。首先可以使用cmd! – PulseJet

1

通過安斯加爾Wiechers答案技術上的作品,但它使用cmd你基本上是用在PowerShell的命令提示符,你失去通過PowerShell中提供的附加功能,這意味着。您可以修改上面的函數以下:

function workon ($env) { & .\Envs\$env\Scripts\activate.ps1 }

這將允許你繼續使用PowerShell命令(不在cmd中工作,如ls)在虛擬環境中

這也假定您的環境保存在。\ Envs中。如果它們在別處,則相應地調整函數中的路徑。如果你是而不是是一個Windows用戶(和我一樣),並且需要關於何處放置該功能以及如何在打開PowerShell時加載它的幫助。以下是幫了我一些額外的資源:

背景:

How to Write a PowerShell Script Module

Importing a PowerShell Module

如何獲得PowerShell來自動加載你的模塊在啓動時:

How to Create a PowerShell Profile

Start PowerShell with modules loaded

0

有一個更簡單的解決方案!只要到你的Python腳本文件夾,其中workon.bat文件存在並創建一個名爲workon.ps1一個新的文件,並添加下面一行到它

iex ("~\Envs\" + $args[0] + "\Scripts\activate.ps1") 

你,如果你保存你virtualenvs其他地方許多需要適當改變這一點,還要設置執行策略以允許腳本。現在,您可以在cmd和PowerShell中使用workon,因爲ps1將在cmd中以powershell和bat執行。

您還可以查看virtualenvwrapper-win的my fork(完全披露:我是powershell部分的作者),它包含一些爲powershell重寫的腳本,並且應該可以在CMD和PowerShell上運行。如果你想複製粘貼,創建兩個文件,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 
+0

我覺得輸入'&cmd/k workon '就像Ansgar Wiechers說的那樣比你提議的要簡單得多 –

+0

@RonG我認爲答案的第二部分是錯誤的*,因爲它涉及切換到cmd,擊敗整點使用PowerShell。我也可以建議使用cmd來代替,這會爲我開箱即用。 – PulseJet