Bash hat <(..)
für die Prozessersetzung. Was entspricht Powershell?
Ich weiß $(...)
, dass es eine gibt , aber sie gibt eine Zeichenfolge zurück, während sie <(..)
eine Datei zurückgibt, aus der der äußere Befehl lesen kann, und die erwartet wird.
Ich bin auch nicht auf der Suche nach einer Pipe-basierten Lösung, sondern etwas, das ich in der Mitte der Kommandozeile festhalten kann.
powershell
IttayD
quelle
quelle
Write-Output "The BITS service is $(Get-Service bits | select -ExpandProperty Stauts)"
um den Status des BITS-Dienstes abzurufen, ohne ihn zuerst in eine Variable zu laden. Mit Blick auf die Prozessersetzung ist dies nicht genau dasselbe, aber es könnte das Problem, mit dem Sie konfrontiert sind, noch lösenpsftp.exe
für SFTP - Übertragungen: seine-b
Option erfordert Befehle bieten auf dem Server ausgeführt werden über eine Datei , die unbequem ist, wenn man nur laufen wollen, sagen wir,mget *
. Wenn PowerShell eine Prozessersetzung hätte, wären Sie in der Lage, so etwas zu tunpsftp.exe -l user -p password somehost -b <( "mget *" )
.Antworten:
Diese Antwort ist NICHT für Sie , wenn Sie:
- selten, wenn überhaupt, externe CLIs verwenden müssen (was im Allgemeinen erstrebenswert ist - native PowerShell-Befehle spielen viel besser zusammen und benötigen keine solche Funktion).
- sind mit Bashs Prozessersetzung nicht vertraut.
Diese Antwort ist für Sie , wenn Sie:
- häufig externe CLIs verwenden (ob aus Gewohnheit oder aufgrund fehlender (guter) PowerShell-nativer Alternativen), insbesondere beim Schreiben von Skripten.
- sind gewöhnt und wissen zu schätzen, was die Prozessersetzung von Bash leisten kann.
- Update : Da PowerShell nun auch auf Unix-Plattformen unterstützt wird, ist diese Funktion von zunehmendem Interesse - siehe diese Funktionsanforderung auf GitHub, was darauf hindeutet, dass PowerShell eine Funktion implementiert, die der Prozessersetzung ähnelt.
In der Unix-Welt wird in Bash / Ksh / Zsh durch eine Prozessersetzung die Befehlsausgabe so behandelt, als wäre es eine temporäre Datei , die nach sich selbst bereinigt. Beispiel
cat <(echo 'hello')
:cat
Wobei die Ausgabe desecho
Befehls als Pfad einer temporären Datei betrachtet wird, die die Befehlsausgabe enthält .In PowerShell-nativen Befehlen ist eine solche Funktion zwar nicht unbedingt erforderlich, sie kann jedoch im Umgang mit externen CLIs hilfreich sein .
Das Emulieren der Funktion in PowerShell ist umständlich , kann sich aber lohnen, wenn Sie es häufig benötigen.
Stellen Sie sich eine Funktion mit dem Namen vor
cf
, die einen Skriptblock akzeptiert, den Block ausführt und seine Ausgabe in ein temporäres Verzeichnis schreibt. Datei, die auf Anforderung erstellt wird, und gibt das Temp zurück. Dateipfad ; z.B:Dies ist ein einfaches Beispiel, das die Notwendigkeit einer solchen Funktion nicht gut veranschaulicht . Ein vielleicht überzeugenderes Szenario ist die Verwendung von
psftp.exe
für SFTP Transfer: sein Charge (automatisiert) Verwendung erfordert eine Eingabe bereitstellt Datei die gewünschten Befehle enthält, während solche Befehle leicht als Zeichenfolge im Fluge erzeugt werden können.Um mit externen Versorgungsunternehmen so weit wie möglich kompatibel zu sein, sollte die temp. Datei sollte UTF-8 verwenden standardmäßig Codierung ohne Stückliste (Byte Order Mark) verwenden, obwohl Sie bei Bedarf eine UTF-8-Stückliste mit anfordern können
-BOM
.Leider kann der automatische Bereinigungsaspekt von Prozessersetzungen nicht direkt emuliert werden, sodass ein expliziter Bereinigungsaufruf erforderlich ist . Die Bereinigung erfolgt durch Aufrufen
cf
ohne Argumente :Für interaktive Nutzung, Sie können die Bereinigung , indem Sie die Bereinigung Aufruf an Ihre automatisieren
prompt
Funktion wie folgt (dieprompt
Funktion , um die Eingabeaufforderung zurückgibt String , sondern auch verwendet werden kann , hinter die Kulissen führen Befehle jedes Mal , wenn die Eingabeaufforderung angezeigt wird, ähnlich wie Bash$PROMPT_COMMAND
Variable); Um die Verfügbarkeit in einer interaktiven Sitzung zu überprüfen, fügen Siecf
Ihrem PowerShell-Profil Folgendes sowie die folgende Definition hinzu :Zur Verwendung in Skripten muss der Block, der
cf
das gesamte Skript verwendet, in einentry
/finally
-Block eingeschlossen werden, in demcf
ohne Argumente für die Bereinigung aufgerufen wird , um sicherzustellen, dass die Bereinigung durchgeführt wird :Hier ist die Implementierung : Erweiterte Funktion
ConvertTo-TempFile
und ihr prägnanter Alias,cf
:Hinweis : Die Verwendung von
New-Module
, für die PSv3 + erforderlich ist, um die Funktion über ein dynamisches Modul zu definieren stellt sicher, dass keine Variablenkonflikte zwischen den Funktionsparametern und Variablen wird, auftreten können.Beachten Sie die Möglichkeit, optional einen Ausgabepfad [Datei] und / oder eine Dateinamenerweiterung anzugeben.
quelle
psftp.exe
, was mich dazu veranlasste, es zu schreiben. Auch wenn es vorzuziehen ist, alles nativ in PowerShell auszuführen, ist dies nicht immer möglich. Das Aufrufen externer CLIs von PowerShell aus geschieht und wird auch weiterhin geschehen. Wenn Sie immer wieder mit CLIs zu tun haben, für die eine Dateieingabe erforderlich ist, die (leichter) im Speicher oder mit einem anderen Befehl erstellt werden kann, kann die Funktion in dieser Antwort Ihr Leben erleichtern.Wenn nicht in doppelte Anführungszeichen eingeschlossen,
$(...)
ein PowerShell-Objekt (oder was auch immer vom beigefügten Code zurückgegeben wird) zurückgegeben, wobei der beigefügte Code zuerst ausgewertet wird. Dies sollte für Ihre Zwecke geeignet sein ("etwas [I] kann in der Mitte der Befehlszeile bleiben"), vorausgesetzt, die Befehlszeile ist PowerShell.Sie können dies testen, indem Sie verschiedene Versionen
Get-Member
weiterleiten oder sogar direkt ausgeben.Wie Sie bemerkt haben, gibt "$ (...)" in doppelten Anführungszeichen nur eine Zeichenfolge zurück.
Auf diese Weise können Sie, wenn Sie beispielsweise den Inhalt einer Datei direkt in eine Zeile einfügen möchten, Folgendes verwenden:
quelle
Get-Content <(Get-ChildItem)
Get-ChildItem | Get-Content
perfekt? Oder könntest du sonst versuchen,Get-Content (Get-ChildItem).FullName
den gleichen Effekt zu erzielen? Sie nähern sich dem möglicherweise aus einer Sicht, die durch einen anderen Skriptansatz stark beeinflusst wird.