Как получить текущий каталог выполняемого командлета
Это должно быть простой задачей, но я видел несколько попыток получить путь к каталогу, где исполняемый командлет находится с переменным успехом. Например, когда я выполняю C:\temp\myscripts\mycmdlet.ps1
с файлом настроек в C:\temp\myscripts\settings.xml
, я бы хотел сохранить C:\temp\myscripts
в переменной внутри mycmdlet.ps1
.
Это одно решение, которое работает (хотя и немного громоздко):
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + '\settings.xml'
Другой предложил это решение, которое работает только в нашей тестовой среде:
$settingspath = '.\settings.xml'
Мне очень нравится последний подход, и я предпочитаю каждый раз анализировать путь к файлу как параметр, но я не могу заставить его работать в моей среде разработки. Что мне делать? Это как-то связано с настройкой PowerShell?
Ответы
Ответ 1
Надежный способ сделать это так же, как вы показали $MyInvocation.MyCommand.Path
.
Использование относительных путей будет основано на $ pwd в PowerShell, текущем каталоге приложения или текущем рабочем каталоге API.NET.
PowerShell v3+:
Используйте автоматическую переменную $PSScriptRoot
.
Ответ 2
Да, это должно работать. Но если вам нужно увидеть абсолютный путь, это все, что вам нужно:
(Get-Item -Path ".\").FullName
Ответ 3
Кажется, самый простой способ - использовать следующую предопределенную переменную:
$PSScriptRoot
about_Automatic_Variables
и about_Scripts
оба состояния:
В PowerShell 2.0 эта переменная действительна только в скриптовых модулях (.psm1). Начиная с PowerShell 3.0, он действителен во всех сценариях.
Я использую это так:
$MyFileName = "data.txt"
$filebase = Join-Path $PSScriptRoot $MyFileName
Ответ 4
Вы также можете использовать:
(Resolve-Path .\).Path
В скобках возвращается объект PathInfo
.
(Доступно с версии PowerShell 2.0.)
Ответ 5
Путь часто равен нулю. Эта функция более безопасна.
function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value;
if($Invocation.PSScriptRoot)
{
$Invocation.PSScriptRoot;
}
Elseif($Invocation.MyCommand.Path)
{
Split-Path $Invocation.MyCommand.Path
}
else
{
$Invocation.InvocationName.Substring(0,$Invocation.InvocationName.LastIndexOf("\"));
}
}
Ответ 6
Пытаться:
(Get-Location).path
или же:
($pwd).path
Ответ 7
Get-Location
вернет текущее местоположение:
$Currentlocation = Get-Location
Ответ 8
Мне нравится однострочное решение :)
$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Ответ 9
Попробуйте следующее:
$WorkingDir = Convert-Path .
Ответ 10
В Powershell 3 и выше вы можете просто использовать
$PSScriptRoot
Ответ 11
Вы думаете, что использование ". \" в качестве пути означает, что это путь вызова. Но не все время. Например, если вы используете его внутри задания ScriptBlock. В этом случае он может указывать на% profile%\Documents.
Ответ 12
То, что стоит, чтобы быть однострочным решением, ниже является рабочим решением для меня.
$currFolderName = (Get-Location).Path.Substring((Get-Location).Path.LastIndexOf("\")+1)
1 в конце должен игнорировать /
.
Благодаря приведенным выше сообщениям с помощью командлета Get-Location.
Ответ 13
Чтобы расширить ответ на @Cradle: вы также можете написать многоцелевую функцию, которая даст вам тот же результат по запросу OP:
Function Get-AbsolutePath {
[CmdletBinding()]
Param(
[parameter(
Mandatory=$false,
ValueFromPipeline=$true
)]
[String]$relativePath=".\"
)
if (Test-Path -Path $relativePath) {
return (Get-Item -Path $relativePath).FullName -replace "\\$", ""
} else {
Write-Error -Message "'$relativePath' is not a valid path" -ErrorId 1 -ErrorAction Stop
}
}
Ответ 14
Если вам просто нужно имя текущего каталога, вы можете сделать что-то вроде этого:
((Get-Location) | Get-Item).Name
Если вы работаете с C:\Temp\Location\MyWorkingDirectory>
Выход
MyWorkingDirectory