Anfang dieses Jahres wurde PowerShell Core unter einer Open Source (MIT)-Lizenz allgemein verfügbar. PowerShell ist kaum eine neue Technologie. Seit der ersten Veröffentlichung für Windows im Jahr 2006 versuchten die Entwickler von PowerShell, die Leistung und Flexibilität von Unix-Shells zu integrieren und gleichzeitig ihre wahrgenommenen Mängel zu beheben, insbesondere die Notwendigkeit der Textmanipulation, um aus der Kombination von Befehlen Nutzen zu ziehen.
Fünf Hauptversionen später ermöglicht PowerShell Core die native Ausführung derselben innovativen Shell- und Befehlsumgebung auf allen wichtigen Betriebssystemen, einschließlich OS X und Linux. Einige (sprich:fast alle ) mag immer noch über die Kühnheit und/oder Kühnheit dieses Windows-geborenen Eindringlings spotten, sich Plattformen anzubieten, die seit jeher starke Shell-Umgebungen haben (zumindest wie von einem Jahrtausend definiert). In diesem Beitrag hoffe ich, dass PowerShell selbst erfahrenen Benutzern Vorteile bieten kann.
Plattformübergreifende Konsistenz
Wenn Sie Ihre Skripts von einer Ausführungsumgebung in eine andere portieren möchten, müssen Sie sicherstellen, dass Sie nur die Befehle und Syntaxen verwenden, die funktionieren. Auf GNU-Systemen würden Sie zum Beispiel das gestrige Datum wie folgt erhalten:
date --date="1 day ago"
Auf BSD-Systemen (wie OS X) würde die obige Syntax nicht funktionieren, da das BSD-Datumsdienstprogramm die folgende Syntax erfordert:
date -v -1d
Da PowerShell unter einer freizügigen Lizenz lizenziert und für alle Plattformen entwickelt wurde, können Sie es mit Ihrer Anwendung ausliefern. Wenn Ihre Skripte also in der Zielumgebung ausgeführt werden, werden sie auf derselben Shell ausgeführt und verwenden dieselben Befehlsimplementierungen wie die Umgebung, in der Sie Ihre Skripte getestet haben.
Objekte und strukturierte Daten
*nix-Befehle und -Dienstprogramme verlassen sich auf Ihre Fähigkeit, unstrukturierte Daten zu verarbeiten und zu bearbeiten. Diejenigen, die jahrelang mit sed
gelebt haben grep
und awk
mag diese Aussage nicht stören, aber es gibt einen besseren Weg.
Wiederholen wir das gestrige Datumsbeispiel in PowerShell. Um das aktuelle Datum zu erhalten, führen Sie Get-Date
aus cmdlet (ausgesprochen "commandlet"):
> Get-Date
Sunday, January 21, 2018 8:12:41 PM
Die Ausgabe, die Sie sehen, ist nicht wirklich eine Textzeichenfolge. Vielmehr handelt es sich um eine Zeichenfolgendarstellung eines .Net Core-Objekts. Genau wie jedes andere Objekt in jeder anderen OOP-Umgebung hat es einen Typ und meistens Methoden, die Sie aufrufen können.
Lassen Sie uns das beweisen:
> $(Get-Date).GetType().FullName
System.DateTime
Der $(...)
Die Syntax verhält sich genau so, wie Sie es von POSIX-Shells erwarten würden – das Ergebnis der Auswertung des Befehls in Klammern ersetzt den gesamten Ausdruck. In PowerShell ist das $ in solchen Ausdrücken jedoch streng optional. Und was am wichtigsten ist, das Ergebnis ist ein .Net-Objekt, kein Text. Also können wir GetType()
aufrufen -Methode für dieses Objekt, um seinen Objekttyp zu erhalten (ähnlich wie Class
Objekt in Java) und der FullName
-Eigenschaft, um den vollständigen Namen des Typs zu erhalten.
Also, wie macht diese Objektorientierung Ihr Leben einfacher?
Erstens können Sie jedes Objekt an Get-Member
weiterleiten cmdlet, um alle Methoden und Eigenschaften anzuzeigen, die es zu bieten hat.
> (Get-Date) | Get-Member
PS /home/yevster/Documents/ArticlesInProgress> $(Get-Date) | Get-Member
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Add Method datetime Add(timespan value)
AddDays Method datetime AddDays(double value)
AddHours Method datetime AddHours(double value)
AddMilliseconds Method datetime AddMilliseconds(double value)
AddMinutes Method datetime AddMinutes(double value)
AddMonths Method datetime AddMonths(int months)
AddSeconds Method datetime AddSeconds(double value)
AddTicks Method datetime AddTicks(long value)
AddYears Method datetime AddYears(int value)
CompareTo Method int CompareTo(System.Object value), int ...
Sie können schnell sehen, dass das DateTime-Objekt einen AddDays
hat mit der Sie schnell das gestrige Datum abrufen können:
> (Get-Date).AddDays(-1)
Saturday, January 20, 2018 8:24:42 PM
Um etwas Aufregenderes zu tun, rufen wir den Wetterdienst von Yahoo an (da kein API-Token erforderlich ist) und rufen Ihr lokales Wetter ab.
$city="Boston"
$state="MA"
$url="https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22${city}%2C%20${state}%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"
Jetzt könnten wir die Dinge auf die altmodische Weise machen und einfach curl $url
ausführen um einen riesigen JSON-Blob zu erhalten, oder...
$weather=(Invoke-RestMethod $url)
Wenn Sie sich den Typ von $weather
ansehen (durch Ausführen von echo $weather.GetType().FullName
), sehen Sie, dass es sich um ein PSCustomObject
handelt . Es ist ein dynamisches Objekt, das die Struktur von JSON widerspiegelt.
Und PowerShell wird begeistert sein, Ihnen mit der Registerkartenvervollständigung bei der Navigation zu helfen. Geben Sie einfach $weather.
ein (achten Sie darauf, das „.“ einzuschließen) und drücken Sie die Tabulatortaste. Sie sehen alle JSON-Schlüssel auf Stammebene. Geben Sie eins ein, gefolgt von einem „.
", drücken Sie erneut die Tabulatortaste, und Sie sehen die untergeordneten Elemente (falls vorhanden).
So können Sie einfach zu den gewünschten Daten navigieren:
> echo $weather.query.results.channel.atmosphere.pressure
1019.0
> echo $weather.query.results.channel.wind.chill
41
Und wenn Sie JSON oder CSV als unstrukturierte Daten herumliegen (oder von einem externen Befehl zurückgegeben) haben, leiten Sie sie einfach in ConvertFrom-Json
oder ConvertFrom-CSV
cmdlet, und Sie können Ihre Daten in schönen, sauberen Objekten haben.
Computing vs. Automatisierung
Wir verwenden Shells für zwei Zwecke. Einer dient zum Rechnen, zum Ausführen einzelner Befehle und zum manuellen Reagieren auf deren Ausgabe. Die andere ist die Automatisierung, um Skripte zu schreiben, die mehrere Befehle ausführen und programmgesteuert auf ihre Ausgabe reagieren.
Ein Problem, das die meisten von uns zu übersehen gelernt haben, ist, dass diese beiden Zwecke unterschiedliche und widersprüchliche Anforderungen an die Shell stellen. Beim Rechnen muss die Hülle lakonisch sein. Je weniger Tastenanschläge ein Benutzer ausführen kann, desto besser. Es spielt keine Rolle, ob das, was der Benutzer getippt hat, für einen anderen Menschen kaum lesbar ist. Skripte hingegen sind Code. Lesbarkeit und Wartbarkeit sind entscheidend. Und hier versagen uns POSIX-Dienstprogramme oft. Während einige Befehle sowohl lakonische als auch lesbare Syntaxen bieten (z. B. -f
und --force
) für einige ihrer Parameter sind die Befehlsnamen selbst auf der Seite der Kürze, nicht der Lesbarkeit.
PowerShell enthält mehrere Mechanismen, um diesen faustischen Kompromiss zu beseitigen.
Erstens eliminiert die Tab-Vervollständigung das Eintippen von Argumentnamen. Geben Sie beispielsweise Get-Random -Mi
ein , drücken Sie die Tabulatortaste und PowerShell vervollständigt das Argument für Sie:Get-Random -Minimum
. Aber wenn Sie wirklich lakonisch sein wollen, müssen Sie nicht einmal die Tabulatortaste drücken. Beispielsweise versteht PowerShell
Get-Random -Mi 1 -Ma 10
weil Mi
und Ma
jede hat einzigartige Vervollständigungen.
Sie haben vielleicht bemerkt, dass alle PowerShell-Cmdlet-Namen eine Verb-Substantiv-Struktur haben. Dies kann die Lesbarkeit des Skripts verbessern, aber Sie möchten wahrscheinlich nicht ständig Get-
eingeben immer wieder in der Kommandozeile. Also nicht! Wenn Sie ein Substantiv ohne Verb eingeben, sucht PowerShell nach einem Get-
Befehl mit diesem Substantiv.
Achtung:Obwohl PowerShell nicht zwischen Groß- und Kleinschreibung unterscheidet, empfiehlt es sich, den ersten Buchstaben des Substantivs groß zu schreiben, wenn Sie beabsichtigen, einen PowerShell-Befehl zu verwenden. Geben Sie beispielsweise date
ein ruft das date
Ihres Systems auf Nützlichkeit. Geben Sie Date
ein ruft PowerShells Get-Date
auf cmdlet.
Und wenn das nicht genug ist, hat PowerShell Aliase, um einfache Namen zu erstellen. Wenn Sie beispielsweise alias -name cd
eingeben , entdecken Sie die cd
Der Befehl in PowerShell ist selbst ein Alias für Set-Location
Befehl.
Zur Erinnerung:Sie erhalten leistungsstarke Tabulatorvervollständigung, Aliase und Substantivvervollständigungen, um Ihre Befehlsnamen kurz, automatisch und konsistent zu halten Kürzung von Parameternamen und gleichzeitig eine reichhaltige, lesbare Syntax für die Skripterstellung.
Also... Freunde?
Dies sind nur einige der Vorteile von PowerShell. Es gibt weitere Funktionen und Cmdlets, die ich nicht besprochen habe (sehen Sie sich Where-Object oder seinen Alias ?
an wenn Sie grep
machen wollen Weinen). Und hey, wenn Sie wirklich Heimweh haben, startet PowerShell gerne Ihre alten nativen Dienstprogramme für Sie. Aber lassen Sie sich genug Zeit, um sich in die objektorientierte Cmdlet-Welt von PowerShell einzugewöhnen, und Sie werden sich vielleicht dabei ertappen, den Weg zurück zu vergessen.