none
pipe object, Verständnisfrage RRS feed

  • Frage

  • als PowerShell newbee hätte ich eine Verständnisfrage

    get-childitem -path c:\users | foreach { copy-item c:\temp\test.txt $($_.fullname)\appdata\local\temp\test.txt}

    warum muss man das Object nochmals in Klammern und mit $ angeben

    so geht es zb. nicht

    get-childitem -path c:\users | foreach { copy-item c:\temp\test.txt $_.fullname\appdata\local\temp\test.txt}

    wenn man die Variable innerhalb der Schleife nur am Bildschirm ausgibt liefert sie korrekt den Fullname



    Freitag, 15. November 2019 18:50

Antworten

  • Moin,

    das in der Pipe gerade verarbeitete Objekt ist in $_ ethalten, was ein Alias auf $PSITEM ist.

    Im letzten Beispiel gibst Du eine bestimmte Property des Objektes einfach aus, da muss man nichts parsen. Wenn Du hingegen

    "$_.Fullname"
    sagst, bekommst Du etwas anderes zurück. Die Evaluierung erfolgt nämlich von links nach rechts, und sobald er was gefunden hat, was man verwenden kann, ist er fertig. Mit $() zwingst Du ihn, den eingeschlossenen Abschnitt zuerst komplett auszurechnen.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    • Als Antwort markiert Dont - Worry Samstag, 16. November 2019 12:52
    Samstag, 16. November 2019 09:30
  • lt. deiner Erklärung müsste es ja sonst im Copy Befehl auch mit $_.Fullname+"\appdat\blahblah" gehen.

    Tut es auch, musst Du nur in Klammern nehmen, sonst ist beim ersten Whitespace-Zeichen (+) der Wert für das Argument zu Ende.

    Und 'Cmdlet' ist ein Wort und muss nicht ausgeschrieben werden.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    • Als Antwort markiert Dont - Worry Sonntag, 17. November 2019 12:33
    Sonntag, 17. November 2019 11:59

Alle Antworten

  • Moin,

    wenn Du ein Objekt an die Konsole ausgibst, hat der Autor ggfls. dafür gesorgt, dass dabei nur eine Property ausgegeben wird. Stimmt die Ansicht des Autors darüber, welche Property dafür sinnvoll ist, mit Deiner überein, kommt es zu dem Missverständnis, das wir gerade erleben.

    Was passiert, wenn Du $() nicht angibst, ist folgendes:

    • der Parser sieht $_ und weiss aus dem Kontext des Cmdlets, dass er daraus einen String machen muss. Das wäre in diesem Fall ein absoluter Pfad, z.B. c:\users\holly
    • danach kommt .FullName - der Parser hängt das an und macht daraus c:\users\holly.fullname
    • das gibt es nicht, daher knallt's

    Evgenij Smirnov

    http://evgenij.smirnov.de

    • Als Antwort vorgeschlagen -- Chris -- Samstag, 16. November 2019 08:22
    Freitag, 15. November 2019 18:58
  • danke Evgenij für die Info

    liegt das Object nach dem Pipe im $ oder im $_  ?

    das von dir beschriebene Verhalten betrifft auch noch vermutlich vorwiegend command-lets - oder?

    Get-ChildItem -Directory -Path "C:\Users" | ForEach-Object {$_.fullName}
    bei meinem Test kommt vermutlich der Ausgabe Parser hinzu, der es richtig macht. Da geht es nämlich (noch)

    Samstag, 16. November 2019 09:23
  • Moin,

    das in der Pipe gerade verarbeitete Objekt ist in $_ ethalten, was ein Alias auf $PSITEM ist.

    Im letzten Beispiel gibst Du eine bestimmte Property des Objektes einfach aus, da muss man nichts parsen. Wenn Du hingegen

    "$_.Fullname"
    sagst, bekommst Du etwas anderes zurück. Die Evaluierung erfolgt nämlich von links nach rechts, und sobald er was gefunden hat, was man verwenden kann, ist er fertig. Mit $() zwingst Du ihn, den eingeschlossenen Abschnitt zuerst komplett auszurechnen.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    • Als Antwort markiert Dont - Worry Samstag, 16. November 2019 12:52
    Samstag, 16. November 2019 09:30
  • Evgenij, danke nochmals für die wirklich sehr gute Erklärung und Information.

    scheinbar gibt es auch noch Unterschiede ob es bei einer Bildschirmausgabe oder in einem Command-Let geparst wird.

    lt. deiner Erklärung müsste es ja sonst im Copy Befehl auch mit $_.Fullname+"\appdat\blahblah" gehen.


    Sonntag, 17. November 2019 10:59
  • lt. deiner Erklärung müsste es ja sonst im Copy Befehl auch mit $_.Fullname+"\appdat\blahblah" gehen.

    Tut es auch, musst Du nur in Klammern nehmen, sonst ist beim ersten Whitespace-Zeichen (+) der Wert für das Argument zu Ende.

    Und 'Cmdlet' ist ein Wort und muss nicht ausgeschrieben werden.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    • Als Antwort markiert Dont - Worry Sonntag, 17. November 2019 12:33
    Sonntag, 17. November 2019 11:59