none
Dot Sourcing über Variable RRS feed

  • Frage

  • Hallo,

    Ich habe mir eine Funktionsbibliothek angelegt und möchte diese über Dot Sourcing in meine laufenden Scripte bei Bedarf einbinden.

    Gebe ich den Pfad direkt an, funktioniert es natürlich, wie es soll. Nun möchte ich aber das Verzeichnis relativ zum laufenden Script setzen, weil das Script auf verschiedenen System laufen soll und von Leuten ausgeführt wird, die in den Scripten nicht noch Pfade anpassen müssen.

    # Folgendes funktioniert:
    . C:\Users\UserName\Documents\Powershell\script.ps1
    
    # Dies funktioniert nicht:
    $ScriptRoot = split-path $PSScriptRoot
    . $ScriptRoot"library.ps1"
    
    # Was allerdings wieder funktioniert:
    $ScriptRoot = split-path $PSScriptRoot"\library.ps1"
    . $ScriptRoot"library.ps1"

    Mit der unteren Variante ist mir zwar erstmal geholfen, aber so ganz verstehe ich nicht, warum die zweite nicht funktioniert und wie ich das besser lösen könnte?

    Für Infos immer dankbar.

    Gruß Arne



    • Bearbeitet Arne Drews Dienstag, 12. April 2016 08:56
    Dienstag, 12. April 2016 08:55

Antworten

  • Hallo,

    schau dir doch mal an, was in $ScriptRoot steht. Höchstwahrscheinlich steht dort

    C:\Users\UserName\Documents\Powershell


    Es fehlt der letzte Backslash!

    Deshalb kannst du es nur so verbinden:

    "$ScriptRoot\library.ps1"

    Du solltest deine Strings immer entweder innerhalb eines Strings verbinden (wie ich oben) oder mit dem Verbindungsoperator "+". Deine letzte Variante mag zwar gehen, sie ist aber nicht wirklich "sauber".

    Du könntest auch das Cmdlet Join-Path verwenden, das genau dafür geschaffen wurde.

    Viele Grüße

    Christoph

    • Als Antwort markiert Arne Drews Donnerstag, 14. April 2016 07:47
    Dienstag, 12. April 2016 09:37
  • > .. C:\Users\UserName\Documents\Powershell\script.ps1
     
    $PSScriptRoot enthält also C:\Users\UserName\Documents\Powershell - es
    ist das Stammverzeichnis des aktuellen Skripts, es enthält nicht den
    Skriptnamen selbst. Das wäre $PSCommandPath :)
     
    > # Dies funktioniert nicht:
    > $ScriptRoot = split-path $PSScriptRoot
     
    Ja - weil in $ScriptRoot nur noch C:\Users\UserName\Documents steht. Das
    letzte Verzeichnis "PowerShell" hast Du mit split-Path abgeschnitten.
     
    > # Was allerdings wieder funktioniert:
    > $ScriptRoot = split-path $PSScriptRoot"\library.ps1"
     
    Ja, weil Du jetzt mit split-Path das library.ps1 abschneidest und damit
    in Deinem $ScriptRoot wieder der vollständige Pfad von oben steht.
     
    Genaugenommen liefert split-path hier ein Array mit 2 Elementen zurück -
    Parent und Leaf. Da Du das nicht in einem Array speicherst, erhältst Du
    in Deinem $ScriptRoot automatisch das erste Element.
     
    • Als Antwort markiert Arne Drews Donnerstag, 14. April 2016 07:47
    Dienstag, 12. April 2016 15:56

Alle Antworten

  • Hallo,

    schau dir doch mal an, was in $ScriptRoot steht. Höchstwahrscheinlich steht dort

    C:\Users\UserName\Documents\Powershell


    Es fehlt der letzte Backslash!

    Deshalb kannst du es nur so verbinden:

    "$ScriptRoot\library.ps1"

    Du solltest deine Strings immer entweder innerhalb eines Strings verbinden (wie ich oben) oder mit dem Verbindungsoperator "+". Deine letzte Variante mag zwar gehen, sie ist aber nicht wirklich "sauber".

    Du könntest auch das Cmdlet Join-Path verwenden, das genau dafür geschaffen wurde.

    Viele Grüße

    Christoph

    • Als Antwort markiert Arne Drews Donnerstag, 14. April 2016 07:47
    Dienstag, 12. April 2016 09:37
  • Hallo Christoph,

    Danke für Deine Antwort.

    Dass der Slash in $ScriptRoot nicht enthalten ist, war mir bewusst, ich habe allerdings vergessen den in obigem Code bei der 2. Variante in die Quotes mitzuschreiben.

    Das Ergebnis bleibt allerdings dasselbe.

    Wenn ich es so mache, wie Du schreibst, also

    . "$ScriptRoot\library.ps1"

    Kommt bei mir ebenfalls ein Fehler:

    Die Benennung "C:\Users\UserName\Documents\library.ps1" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms 
    erkannt.

    Allerdings stimmt der Pfad, weswegen ich weiterhin verwundert bin, warum es scheinbar nur mit der dritten Variante aus #1 funktioniert.

    gruß Arne

    Dienstag, 12. April 2016 10:31
  • Könnte es daran liegen, dass du mal $ScriptRoot und mal $PSScriptRoot benutzt?

    Was genau ist denn der Inhalt der Varibalen? Hast du überprüft, dass darin wirklich der richtige Ordnerpfad steht?

    Dienstag, 12. April 2016 11:25
  • Hi,

    Ja, ich habe mir das ja ausgeben lassen, zumindest, was bei meinem "berechneten" $ScriptRoot rauskommt.

    Ich habe allerdings nicht überprüft, was in $PSScriptRoot steht, das habe ich aus einem Tutorial übernommen und blind geglaubt, dass das der komplette Pfad inkl. Script-Namen ist. Daher auch das split-path, was ich verwendet habe.

    Rein begrifflich macht es ja auch schon gar keinen Sinn, da es ja Root heisst und nicht Path.

    Wie dem auch sei, ich habe das jetzt mal mit Deinem Tipp und direkter Verwendung von $PSScriptRoot verwendet und damit funktioniert es:

    . "$PSScriptRoot\library.ps1"

    Danke für Deine Infos.

    Gruß Arne

    Dienstag, 12. April 2016 11:41
  • > .. C:\Users\UserName\Documents\Powershell\script.ps1
     
    $PSScriptRoot enthält also C:\Users\UserName\Documents\Powershell - es
    ist das Stammverzeichnis des aktuellen Skripts, es enthält nicht den
    Skriptnamen selbst. Das wäre $PSCommandPath :)
     
    > # Dies funktioniert nicht:
    > $ScriptRoot = split-path $PSScriptRoot
     
    Ja - weil in $ScriptRoot nur noch C:\Users\UserName\Documents steht. Das
    letzte Verzeichnis "PowerShell" hast Du mit split-Path abgeschnitten.
     
    > # Was allerdings wieder funktioniert:
    > $ScriptRoot = split-path $PSScriptRoot"\library.ps1"
     
    Ja, weil Du jetzt mit split-Path das library.ps1 abschneidest und damit
    in Deinem $ScriptRoot wieder der vollständige Pfad von oben steht.
     
    Genaugenommen liefert split-path hier ein Array mit 2 Elementen zurück -
    Parent und Leaf. Da Du das nicht in einem Array speicherst, erhältst Du
    in Deinem $ScriptRoot automatisch das erste Element.
     
    • Als Antwort markiert Arne Drews Donnerstag, 14. April 2016 07:47
    Dienstag, 12. April 2016 15:56