usar tutorial script como commands comandos powershell

tutorial - Powershell: ¿resolver camino que podría no existir?



powershell tutorial (10)

Estoy tratando de procesar una lista de archivos que pueden o no estar actualizados y pueden existir o no. Al hacerlo, necesito resolver la ruta completa de un elemento, aunque el elemento se pueda especificar con rutas relativas. Sin embargo, Resolve-Path imprime y produce errores cuando se utiliza con un archivo inexistente.

Por ejemplo, ¿Cuál es la forma más simple y limpia de resolver "./newdir/newfile.txt" a "C:/Current/Working/Directory/newdir/newfile.txt" en Powershell ?

Tenga en cuenta que el método estático de System.IO.Path usa con el directorio de trabajo del proceso, que no es la ubicación actual de powershell.


Aquí hay una respuesta aceptada, pero es bastante larga y hay una alternativa más simple disponible.

En cualquier versión reciente de Powershell, puede usar Test-Path -IsValid -Path ''C:/Probably Fake/Path.txt''

Esto simplemente verifica que no haya caracteres ilegales en la ruta y que la ruta se pueda usar para almacenar un archivo. Si el destino no existe, a Test-Path no le importará en este caso, solo se le pedirá que pruebe si la ruta proporcionada es potencialmente válida.


Creo que estás en el camino correcto. Simplemente use [Environment] :: CurrentDirectory para establecer la noción de .NET del directorio actual del proceso, por ejemplo:

[Environment]::CurrentDirectory = $pwd [IO.Path]::GetFullPath("./xyz")


Cuando Resolve-Path falla debido a que el archivo no existe, se puede acceder a la ruta completamente resuelta desde el objeto de error lanzado.

Puede usar una función como la siguiente para corregir Resolve-Path y hacer que funcione como esperaba.

function Force-Resolve-Path { <# .SYNOPSIS Calls Resolve-Path but works for files that don''t exist. .REMARKS From http://devhawk.net/blog/2010/1/22/fixing-powershells-busted-resolve-path-cmdlet #> param ( [string] $FileName ) $FileName = Resolve-Path $FileName -ErrorAction SilentlyContinue ` -ErrorVariable _frperror if (-not($FileName)) { $FileName = $_frperror[0].TargetObject } return $FileName }


Descubrí que lo siguiente funciona bastante bien.

$workingDirectory = Convert-Path (Resolve-Path -path ".") $newFile = "newDir/newFile.txt" Do-Something-With "$workingDirectory/$newFile"

Convert-Path se puede utilizar para obtener la ruta como una cadena, aunque este no es siempre el caso. Vea this entrada en COnvert-Path para más detalles.


Esto tiene la ventaja de no tener que establecer el directorio actual de CLR Environment:

[IO.Path]::Combine($pwd,"non/existing/path")

NOTA

Esto no es funcionalmente equivalente a la respuesta de x0n . System.IO.Path.Combine solo combina segmentos de ruta de cadena. Su utilidad principal es evitar que el desarrollador tenga que preocuparse por las barras. GetUnresolvedProviderPathFromPSPath recorrerá la ruta de entrada relativa al presente directorio de trabajo, de acuerdo con . ''s y .. '' s.


Puedes simplemente configurar -errorAction como "SilentlyContinue" y usar Resolve-Path

5 > (Resolve-Path ./AllFilerData.xml -ea 0).Path C:/Users/Andy.Schneider/Documents/WindowsPowerShell/Scripts/AllFilerData.xml 6 > (Resolve-Path ./DoesNotExist -ea 0).Path 7 >


Usted quiere:

c:/path/exists/> $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath("./nonexist/foo.txt")

devoluciones:

c:/path/exists/nonexists/foo.txt

Esto tiene la ventaja de trabajar con PSPaths, no con rutas de sistema de archivos nativas. Un PSPAth puede no asignar 1-1 a una ruta del sistema de archivos, por ejemplo, si monta una unidad psdrive con un nombre de unidad de varias letras.

-Oisin


Verifique si el archivo existe antes de resolver:

if(Test-Path ./newdir/newfile.txt) { (Resolve-Path ./newdir/newfile.txt).Path }


Join-Path (Resolve-Path .) newdir/newfile.txt


function Get-FullName() { [CmdletBinding()] Param( [Parameter(ValueFromPipeline = $True)] [object[]] $Path ) Begin{ $Path = @($Path); } Process{ foreach($p in $Path) { if($p -eq $null -or $p -match ''^/s*$''){$p = [IO.Path]::GetFullPath(".");} elseif($p -is [System.IO.FileInfo]){$p = $p.FullName;} else{$p = [IO.Path]::GetFullPath($p);} $p; } } }