PowerShell: запустить команду из каталога скрипта - PullRequest
128 голосов
/ 18 января 2011

У меня есть скрипт PowerShell, который делает некоторые вещи, используя текущий каталог скрипта. Поэтому, когда внутри этого каталога, запуск .\script.ps1 работает правильно.

Теперь я хочу вызвать этот скрипт из другой директории, не меняя ссылочную директорию скрипта. Поэтому я хочу вызвать ..\..\dir\script.ps1 и все еще хочу, чтобы этот скрипт вел себя так, как он вызывался из своего каталога.

Как мне это сделать или как изменить скрипт, чтобы он мог запускаться из любого каталога?

Ответы [ 6 ]

177 голосов
/ 18 января 2011

Вы хотите сказать, что вам нужен собственный путь скрипта, чтобы вы могли ссылаться на файл рядом со скриптом?Попробуйте это:

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

Вы можете получить много информации из $ MyInvocation и его свойств.

Если вы хотите сослаться на файл в текущем рабочем каталоге, вы можете использовать Resolve-Path или Get-ChildItem:

$filepath = Resolve-Path "somefile.txt"

EDIT (на основе комментария от OP):

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

# do stuff, call ant, etc

# now back to previous directory
Pop-Location

Возможно, есть и другие способы достижения чего-то подобного с помощью Invoke-Command.

31 голосов
/ 18 января 2011

Если вы вызываете собственные приложения, вам нужно беспокоиться о [Environment]::CurrentDirectory, а не о текущем каталоге $PWD PowerShell. По какой-то причине, которая ускользает от меня, PowerShell не устанавливает текущий рабочий каталог процесса при установке Set-Location или Push-Location , поэтому вам необходимо убедиться, что вы делаете это, если вы запускаете приложения (или командлеты), которые ожидают его установки.

В сценарии вы можете сделать это:

Push-Location $MyInvocation.MyCommand.Path
[Environment]::CurrentDirectory = $PWD
##  Your Script Code ...
Pop-Location
[Environment]::CurrentDirectory = $PWD

Нет надежной альтернативы этому. Многие из нас помещают строку в нашу функцию приглашения, чтобы установить [Environment] :: CurrentDirectory ... но это не поможет вам, когда вы меняете местоположение в скрипте.

Последнее замечание: $PWD не всегда является допустимым CurrentDirectory (например, вы можете записать CD в поставщика реестра), поэтому, если вы хотите вставить это в приглашение или в функции-оболочки для командлетов * -Location, вам нужно использовать:

[Environment]::CurrentDirectory = Get-Location -PSProvider FileSystem
29 голосов
/ 06 мая 2014

Есть ответы с большим количеством голосов, но когда я прочитал ваш вопрос, я подумал, что вы хотите знать каталог, в котором находится скрипт, а не тот, где работает скрипт.Вы можете получить информацию с помощью автоматических переменных 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.

12 голосов
/ 19 января 2011

Я часто использовал следующий код для импорта модуля, который находится в том же каталоге, что и запущенный скрипт.Сначала он получает каталог, из которого выполняется powershell

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

import-модуль "$ currentPath \ sqlps.ps1"

3 голосов
/ 06 декабря 2017

Это будет нормально работать.

Push-Location $PSScriptRoot

Write-Host CurrentDirectory $CurDir
2 голосов
/ 16 марта 2015

Ну, я некоторое время искал решение для этого, без каких-либо сценариев только из CLI.Вот как я это делаю xD:

  • Перейдите в папку, из которой вы хотите запустить скрипт (важно, чтобы у вас были дополнения на вкладках)

    ..\..\dir

  • Теперь окружите локацию двойными кавычками, а внутри них добавьте cd, чтобы мы могли вызвать другой экземпляр powershell.

    "cd ..\..\dir"

  • Добавить еще одну команду для запуска скрипта, разделенную ;, с разделителем команд в 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"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...