Wann immer ich auf ein allgemeines Modul oder Skript verweisen muss, verwende ich gerne Pfade relativ zur aktuellen Skriptdatei. Auf diese Weise kann mein Skript immer andere Skripte in der Bibliothek finden.
Was ist die beste Standardmethode zum Bestimmen des Verzeichnisses des aktuellen Skripts? Derzeit mache ich:
$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
Ich weiß, dass Sie in Modulen (.psm1) $PSScriptRoot
diese Informationen abrufen können , aber das wird nicht in regulären Skripten (dh .ps1-Dateien) festgelegt.
Wie kann kanonisch der Speicherort der aktuellen PowerShell-Skriptdatei ermittelt werden?
powershell
powershell-2.0
Aaron Jensen
quelle
quelle
Antworten:
PowerShell 3+
PowerShell 2
Vor PowerShell 3 gab es keinen besseren Weg, als die
MyInvocation.MyCommand.Definition
Eigenschaft nach allgemeinen Skripten abzufragen. Ich hatte die folgende Zeile oben in praktisch jedem PowerShell-Skript, das ich hatte:quelle
Split-Path
wird hier verwendet?Split-Path
wird mit dem-Parent
Parameter verwendet, um das aktuelle Verzeichnis ohne den Namen des aktuell ausgeführten Skripts zurückzugeben.$PSScriptRoot
ist (Split-Path -Parent
angewendet auf)$MyInvocation.MyCommand.Path
, nicht$MyInvocation.MyCommand.Definition
, obwohl sie sich im obersten Bereich eines Skripts gleich verhalten (was der einzig sinnvolle Ort ist, von dem aus zu diesem Zweck aufgerufen werden kann). Beim Aufruf innerhalb einer Funktion oder eines Skriptblocks gibt der erstere die leere Zeichenfolge zurück, während der letztere die Definition des Funktionskörpers / Skriptblocks als Zeichenfolge (ein Teil des PowerShell-Quellcodes) zurückgibt .Wenn Sie ein V2-Modul erstellen, können Sie eine automatische Variable namens verwenden
$PSScriptRoot
.Über PS> Hilfe auto_variable
quelle
$PSCommandPath Contains the full path and file name of the script that is being run. This variable is valid in all scripts.
Für PowerShell 3.0
Die Funktion ist dann:
quelle
Für PowerShell 3+
Ich habe diese Funktion in mein Profil aufgenommen. Es funktioniert in ISE auch mit F8/ Run Selection.
quelle
Vielleicht fehlt mir hier etwas ... aber wenn Sie das aktuelle Arbeitsverzeichnis möchten, können Sie dies einfach verwenden:
(Get-Location).Path
für eine Zeichenfolge oderGet-Location
für ein Objekt.Es sei denn, Sie beziehen sich auf so etwas, was ich verstehe, nachdem ich die Frage erneut gelesen habe.
quelle
function Get-Script-Directory { $scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value return Split-Path $scriptInvocation.MyCommand.Path } $hello = "hello" Write-Host (Get-Script-Directory) Write-Host $hello
Speichern Sie das und führen Sie es aus einem anderen Verzeichnis aus. Sie zeigen den Pfad zum Skript.Sehr ähnlich zu bereits veröffentlichten Antworten, aber Piping scheint eher PowerShell-ähnlich zu sein:
quelle
Ich benutze die automatische Variable
$ExecutionContext
. Es funktioniert ab PowerShell 2 und höher.quelle
Es dauerte eine Weile, bis ich etwas entwickelt hatte, das die akzeptierte Antwort in eine robuste Funktion verwandelte.
Bei anderen bin ich mir nicht sicher, aber ich arbeite in einer Umgebung mit Computern auf PowerShell Version 2 und 3, daher musste ich beide verarbeiten. Die folgende Funktion bietet einen eleganten Fallback:
Dies bedeutet auch, dass sich die Funktion eher auf den Skriptbereich als auf den Bereich der Eltern bezieht, wie von Michael Sorens in einem seiner Blog-Beiträge beschrieben .
quelle
Ich musste den Namen des Skripts kennen und wissen, woher es ausgeführt wird.
Das Präfix "$ global:" in der MyInvocation-Struktur gibt den vollständigen Pfad und den Skriptnamen zurück, wenn es sowohl vom Hauptskript als auch von der Hauptzeile einer importierten .PSM1-Bibliotheksdatei aufgerufen wird. Es funktioniert auch innerhalb einer Funktion in einer importierten Bibliothek.
Nachdem ich viel herumgespielt hatte, entschied ich mich für $ global: MyInvocation.InvocationName. Es funktioniert zuverlässig mit CMD-Start, Run With Powershell und ISE. Sowohl lokale als auch UNC-Starts geben den richtigen Pfad zurück.
quelle
ParameterArgumentValidationErrorNullNotAllowed
Ausnahme ausgelöst .Ich verwende immer dieses kleine Snippet, das für PowerShell und ISE auf die gleiche Weise funktioniert :
quelle
Ich habe festgestellt, dass die hier veröffentlichten älteren Lösungen unter PowerShell V5 bei mir nicht funktionieren. Ich habe mir das ausgedacht:
quelle
Sie können auch überlegen,
split-path -parent $psISE.CurrentFile.Fullpath
ob eine der anderen Methoden fehlschlägt. Insbesondere wenn Sie eine Datei ausführen, um eine Reihe von Funktionen zu laden, und diese Funktionen dann in der ISE-Shell ausführen (oder wenn Sie ausgewählt ausführen), scheint die oben beschriebeneGet-Script-Directory
Funktion nicht zu funktionieren.quelle
$PSCommandPath
funktioniert in der ISE, solange Sie das Skript zuerst speichern und die gesamte Datei ausführen. Andernfalls führen Sie kein Skript aus. Sie "fügen" nur Befehle in die Shell ein.Unter Verwendung von Stücken aus all diesen Antworten und den Kommentaren habe ich dies für jeden zusammengestellt, der diese Frage in Zukunft sieht. Es deckt alle in den anderen Antworten aufgeführten Situationen ab
quelle
quelle