У меня есть сценарий PowerShell, который кое-что делает, используя текущий каталог сценария. Итак, внутри этого каталога все .\script.ps1
работает правильно.
Теперь я хочу вызвать этот сценарий из другого каталога, не меняя каталог, на который ссылается сценарий. Итак, я хочу вызвать ..\..\dir\script.ps1
и по-прежнему хочу, чтобы этот сценарий вел себя так, как он был вызван из своего каталога.
Как мне это сделать или как изменить сценарий, чтобы он мог запускаться из любого каталога?
источник
ant
с некоторыми параметрами. Поэтому мне нужно позвонитьant
из этой папки, чтобы убедиться, что он правильно нашел файл конфигурации. В идеале я ищу что-нибудь для временного изменения каталога выполнения локально внутри этого сценария.Push-Location
иPop-Location
Есть ответы с большим количеством голосов, но когда я прочитал ваш вопрос, я подумал, что вы хотите знать каталог, в котором находится скрипт, а не тот, где скрипт запущен. Вы можете получить информацию с помощью автоматических переменных 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
не о$PWD
текущем каталоге PowerShell . По разным причинам PowerShell не устанавливает текущий рабочий каталог процесса при Set-Location или Push-Location, поэтому вам необходимо убедиться, что вы это сделали, если вы запускаете приложения (или командлеты), которые ожидают его установки.В сценарии вы можете сделать это:
$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
Этому нет надежной альтернативы. Многие из нас помещают строку в нашу функцию приглашения, чтобы установить [Environment] :: CurrentDirectory ... но это не помогает вам, когда вы меняете местоположение в сценарии.
Два примечания о причине, по которой это не устанавливается PowerShell автоматически:
$PWD
рабочий каталог, но есть только один процесс и только одна среда.$PWD
это не всегда законный CurrentDirectory (например, вы можете записать CD в провайдер реестра).Если вы хотите поместить его в свое приглашение (которое будет работать только в основном пространстве выполнения, однопоточное), вам необходимо использовать:
источник
.\_/.
- это убило половину моего дня! Народ, серьезно? Серьезно? ..[Environment]::CurrentDirectory
если он отличается от$PWD
. Правильнее было бы сохранить его в переменной,$origEnvDir = [Environment]::CurrentDirectory
а затем восстановить[Environment]::CurrentDirectory = $origEnvDir
.Я часто использовал следующий код для импорта модуля, который находится в том же каталоге, что и запущенный скрипт. Сначала он получит каталог, из которого запущен powershell
источник
Это сработает нормально.
Push-Location $PSScriptRoot Write-Host CurrentDirectory $CurDir
источник
Pop-Location
в конце, чтобы вернуть путь в исходное состояние.Что ж, я какое-то время искал решение для этого, без каких-либо скриптов только из CLI. Вот как я это делаю xD:
Перейдите в папку, из которой вы хотите запустить скрипт (важно, чтобы у вас были дополнения вкладок)
..\..\dir
Теперь заключите location в двойные кавычки и добавьте внутри них
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"
источник
Я сделал однострочник из решения @ JohnL:
$MyInvocation.MyCommand.Path | Split-Path | Push-Location
источник