簡體   English   中英

PowerShell:從腳本目錄運行命令

[英]PowerShell: Run command from script's directory

我有一個 PowerShell 腳本,它使用腳本的當前目錄執行一些操作。 因此,當在該目錄中時,運行.\\script.ps1可以正常工作。

現在我想從不同的目錄調用該腳本而不更改腳本的引用目錄。 所以我想調用..\\..\\dir\\script.ps1並且仍然希望該腳本按照從其目錄內部調用的方式運行。

我該怎么做,或者我如何修改腳本以便它可以從任何目錄運行?

你的意思是你想要腳本自己的路徑,以便你可以引用腳本旁邊的文件? 試試這個:

$scriptpath = $MyInvocation.MyCommand.Path
$dir = Split-Path $scriptpath
Write-host "My directory is $dir"

您可以從 $MyInvocation 及其屬性中獲取大量信息。

如果要引用當前工作目錄中的文件,可以使用 Resolve-Path 或 Get-ChildItem:

$filepath = Resolve-Path "somefile.txt"

編輯(基於 OP 的評論):

# temporarily change to the correct folder
Push-Location $dir

# do stuff, call ant, etc

# now back to previous directory
Pop-Location

可能還有其他使用 Invoke-Command 實現類似功能的方法。

有很多投票的答案,但是當我閱讀您的問題時,我以為您想知道腳本所在的目錄,而不是腳本運行的目錄。 您可以使用powershell的自動變量獲取信息

$PSScriptRoot     # the directory where the script exists, not the
                  # target directory the script is running in
$PSCommandPath    # the full path of the script

例如,我有一個$profile腳本,用於查找 Visual Studio 解決方案文件並啟動它。 一旦解決方案文件啟動,我想存儲完整路徑。 但我想保存原始腳本所在的文件。 所以我使用了$PsScriptRoot

如果您正在調用本機應用程序,則需要擔心[Environment]::CurrentDirectory而不是 PowerShell 的$PWD當前目錄。 由於各種原因,PowerShell 在您設置位置或推送位置時不會設置進程的當前工作目錄,因此如果您正在運行希望設置它的應用程序(或 cmdlet),您需要確保這樣做。

在腳本中,您可以執行以下操作:

$CWD = [Environment]::CurrentDirectory

Push-Location $MyInvocation.MyCommand.Path
[Environment]::CurrentDirectory = $PWD
##  Your script code calling a native executable
Pop-Location

# Consider whether you really want to set it back:
# What if another runspace has set it in-between calls?
[Environment]::CurrentDirectory = $CWD

沒有萬無一失的替代方案。 我們很多人把線在我們的提示功能設定[環境] :: currentDirectory所...但是,這並不能幫助你,當你改變一個腳本的位置。

關於 PowerShell 未自動設置的原因的兩個說明:

  1. PowerShell 可以是多線程的。 您可以在單個進程中同時運行多個運行空間(請參閱 RunspacePool 和 PSThreadJob 模塊)。 每個運行空間都有自己的$PWD當前工作目錄,但只有一個進程和一個環境。
  2. 即使您是單線程的, $PWD也不總是合法的 CurrentDirectory(例如,您可能會 CD 到注冊表提供程序中)。

如果你想把它放到你的提示中(它只會在主運行空間中運行,單線程),你需要使用:

[Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem

我經常使用以下代碼導入與運行腳本位於同一目錄下的模塊。 它將首先獲取運行 powershell 的目錄

$currentPath=Split-Path ((Get-Variable MyInvocation -Scope 0).Value).MyCommand.Path

導入模塊“$currentPath\\sqlps.ps1”

這會工作得很好。

Push-Location $PSScriptRoot

Write-Host CurrentDirectory $CurDir

好吧,我一直在為此尋找解決方案,而沒有任何來自 CLI 的腳本。 這就是我的做法 xD:

  • 導航到要從中運行腳本的文件夾(重要的是您有選項卡完成)

    ..\\..\\dir

  • 現在用雙引號將 location 括起來,並在其中添加cd ,這樣我們就可以調用 powershell 的另一個實例。

    "cd ..\\..\\dir"

  • 添加另一個命令以運行由;分隔的腳本 , with 是powershell中的命令分隔符

    "cd ..\\..\\dir\\; script.ps1"

  • 最后用另一個powershell實例運行它

    start powershell "cd..\\..\\dir\\; script.ps1"

這將打開新的 powershell 窗口,轉到..\\..\\dir ,運行script.ps1並關閉窗口。


注意“;” 只是分開命令,就像你一個一個地輸入它們一樣,如果第一個失敗,第二個將運行,然后再運行,然后再運行......如果你想保持新的powershell窗口打開,你在傳遞的命令中添加 -noexit 。 請注意,我首先導航到所需的文件夾,以便我可以使用制表符補全(您不能使用雙引號)。

start powershell "-noexit cd..\\..\\dir\\; script.ps1"

使用雙引號""以便您可以傳遞名稱中帶有空格的目錄,例如,

start powershell "-noexit cd '..\\..\\my dir'; script.ps1"

我用@JohnL 的解決方案做了一個單行:

$MyInvocation.MyCommand.Path | Split-Path | Push-Location

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM