powershell - principales - Cómo obtener el directorio actual del cmdlet que se está ejecutando
que es un cmdlet (12)
El método más fácil parece ser usar la siguiente variable predefinida:
$PSScriptRoot
about_Automatic_Variables
y about_Scripts
ambos dicen:
En PowerShell 2.0, esta variable es válida solo en los módulos de script (.psm1). A partir de PowerShell 3.0, es válido en todos los scripts.
Lo uso así:
$MyFileName = "data.txt"
$filebase = Join-Path $PSScriptRoot $MyFileName
Esta debería ser una tarea simple, pero he visto varios intentos de cómo obtener la ruta al directorio donde se encuentra el cmdlet ejecutado con éxito mixto. Por ejemplo, cuando ejecuto c:/temp/myscripts/mycmdlet.ps1
que tiene un archivo de configuración en c:/temp/myscripts/settings.xml
me gustaría poder almacenar c:/temp/myscripts
en una variable dentro de mycmdlet.ps1
.
Esta es una solución que funciona (aunque es un poco engorrosa):
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + ''/settings.xml''
Otro sugirió esta solución que solo funciona en nuestro entorno de prueba:
$settingspath = ''./settings.xml''
Me gusta mucho este último enfoque y prefiero tener que analizar el camino del archivo como un parámetro cada vez, pero no puedo hacer que funcione en mi entorno de desarrollo. ¿Alguien tiene una sugerencia sobre qué hacer? ¿Tiene algo que ver con la configuración de PowerShell?
En Powershell 3 y superior, simplemente puede usar
$PSScriptRoot
Get-Location devolverá la ubicación actual
$ Ubicación actual = Get-Location
La forma confiable de hacer esto es como usted mostró $MyInvocation.MyCommand.Path
.
El uso de rutas relativas se basará en $ pwd, en PowerShell, en el directorio actual de una aplicación o en el directorio de trabajo actual de una API de .NET.
La ruta es a menudo nula. Esta función es más segura.
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("/"));
}
}
Me gusta la solution de una línea :)
$scriptDir = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Para ampliar la respuesta de @Cradle: también puede escribir una función multipropósito que le dará el mismo resultado según la pregunta del 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
}
}
Pensarías que usar ''. /' Como ruta significa que es la ruta de invocación. Pero no todo el tiempo. Ejemplo, si lo usa dentro de un trabajo ScriptBlock. En ese caso, podría apuntar a% profile% / Documents.
Prueba esto:
$WorkingDir = Convert-Path .
Pruebe algo de esto: (Get-Location) .path o ($ pwd) .path
Sí, eso debería funcionar. Pero si necesita ver el camino absoluto, esto es todo lo que necesita:
(Get-Item -Path "./").FullName
También puedes usar:
(Resolve-Path ./).Path
La parte entre paréntesis devuelve un objeto PathInfo
.
(Disponible desde PowerShell 2.0)