Eigentlich verbringe ich die meiste Zeit in Linux auf zsh. Aber in der Arbeit wird Windows verwendet und dann muss man sehen, wo man bleibt. Für GUIs habe ich keine Nerven, also habe ich mir PowerShell näher angesehen. Und ich war wirklich überrascht.
Das kann man ja benutzen
Ich versuche nur Software zu lernen, die ich auch privat benutzen würde. Das bedeutet in erster Linie freie Open Source (Linux) Software. Wie schneidet PowerShell hier ab?
Erste Überraschung: PowerShell ist MIT lizenziert. Das war nicht immer so und es gibt auch proprietäre Varianten. Aber zumindest kann man das ohne schlechtes Gewissen mal ausprobieren.
Zweite Überraschung: PowerShell funktioniert unter Linux, macOs und Windows.
Um ehrlich zu sein, das hätte ich nicht von einer Microsoft-Technologie erwartet.
Keine Unix-Shell
Wer bash, sh, zsh, ash und all die Verwandten kennt, wird bald ein paar Unterschiede feststellen:
Die Namen der Befehle
Befehle folgen dem Muster Verb-Objekt. Hier eine kleine Übersetzungstabelle als Beispiel:
normale shell | powershell |
---|---|
ls |
Get-ChildItem |
cd |
Set-Location |
echo |
Write-Host oder Write-Output |
cat |
Get-Content |
man |
Get-Help |
Diese Idee finde ich richtig gut. Die Lesbarkeit ist deutlich besser und man kann ungefähr raten, was Befehle machen werden. Andersherum funktioniert es für mich noch nicht (vielleicht aber eine Frage der Erfahrung): Wenn ich einen Befehl suche, kann ich nicht einfach raten, wie der richtige Befehl heißen könnte.
Andererseits sind die Befehle in PowerShell viel länger als unter Unix. In der Praxis muss man deshalb deutlich mehr tippen, das ist nervig in einer Repl.
Pipes funktionieren ganz anders
Pipes (|
) sind das beste Feature von Shells. In zsh benutze ich sie ungefähr einmal pro Minute. In PowerShell gibt es auch Shells, aber sie funktionieren anders. Anstatt Strings werden Objekte an den nächsten Befehl weitergegeben. Manchmal macht das einen Unterschied.
Ein Standardbeispiel ist: Finde die Namen der 3 größten Dateien in einem Directory.
Das klingt eigentlich nach etwas, worin eine shell gut sein sollte. Es geht auch, aber es ist schon ein wenig frickelig. Diese Lösung habe ich mir ausgedacht:
ls -l | sort --numeric --key 5 | tail -3 | awk '{print $9}'
In PowerShell ist das eleganter.
Get-ChildItem | Sort-Object -Property Size | Select-Object -Last 3 -Property Name
Im Prinzip passiert ja hier das gleiche, aber die PowerShell-Lösung ist lesbarer und wahrscheinlich auch stabiler.
Richtig gut
An ein paar Stellen war ich wirklich sehr angetan von der Powershell. Zum Beispiel, Text farbig ausgeben:
Write-Host -ForegroundColor red "Warnung!"
In einer traditionellen Shell muss man sich dafür mit ANSI-Escapecodes herumschlagen. Warum gibt es solche Flags eigentlich nicht in echo
? Das ist sooo praktisch!
Richtig nervig
Am meisten ärgert mich an der PowerShell, dass die Tab-Completion unter Windows nicht gut ist. Unter Linux geht es. Ich verstehe nicht, woran das liegt.
Deshalb verwende ich PowerShell auch hauptsächlich für Skripte, nicht in der Repl.
Wie eine ordentliche Programmiersprache
PowerShell fühlt sich an vielen Stellen wie eine Programmiersprache an:
- lesbare for-Schleifen und if-Verzweigungen
- Klassen
- Exceptions
- Funktionen mit benannten Parametern (kein $1 und $2)
- Dokumentation
PowerShell ist hier näher an Python dran als an bash.
Skripte bleiben wartbar
Mit Shell-Skripten kann man alles machen, aber man sollte nicht.
Wenn sie zu lange werden, ist man gut beraten, sie in einer richtigen Programmiersprache neu zu schreiben. Was bedeutet “zu lang”? Google sagt ab 100 Zeilen - Ich persönlich finde die Grenze ist bei 10 Zeilen.
Zu meinem Erstaunen sind PowerShell-Skripte deutlich besser wartbar als Shell-Skripte. Ein paar Hundert Zeilen sind gar kein Problem (wenn man Funktionen und gute Namen verwendet).
Fazit
PowerShell ist eigentlich ziemlich cool. Es ist wartbar, einigermaßen ausdrucksstark und flexibel. Und FOSS. Und Cross-Plattform.
Insgesamt fühlt es sich an wie eine gute Mischung aus bash und Python. Ob das eine Nische ist, die gefüllt werden musste, kann jeder selbst entscheiden.
Ich finde, es lohnt sich damit mal herum zu experimentieren.
Titelbild: https://unsplash.com/de/fotos/person-mit-schwarzer-muschel-s_JFRLuCg8g
Quellen: keine
> Insgesamt fühlt es sich an wie eine gute Mischung aus bash und Python.
Das gibt es schon: Xonsh ;-)
Inzwischen meine Standard-Shell.
Wirklich? Ich habe noch nie jemandem gesehen, der die "in echt" benutzt. Findest du denn, dass sich die pipes gut mit den Python Funktionen vertragen?
Finde ich super, dass die PowerShell (Core) mal Erwähnung in einem Artikel findet :) Nutze PowerShell täglich auf Arbeit und das objektorientierte Scripting ist ein absoluter Segen, wenn man umfangreiche Datensätze verarbeiten will. Für's NAS muss ich aktuell einige Bash-Skripte schreiben und da vermisse ich öfter mal den Komfort der PS ^^
> Wenn ich einen Befehl suche, kann ich nicht einfach raten, wie der richtige Befehl heißen könnte.
Kein Wundermittel, aber mir hilft öfter der Befehl 'Get-Command' weiter. Ohne Parameter werden alle verfügbaren Kommandos ausgegeben - das lässt sich aber mit -Verb und -Noun eingrenzen. Bspw. 'Get-Command -Noun Request' (hier mit Wildcards) um alle Befehle mit dem Nomen 'Request' anzuzeigen.
> PowerShell fühlt sich an vielen Stellen wie eine Programmiersprache an
Im Hintergrund werkelt das .NET (Core) Framework von Microsoft, welches die Befehle auswertet. Unter Windows merkt man das deutlicher, da dort gerne mal C#-Methoden in Skripten zu finden sind. Prinzipiell können also komplette .NET-Anwendungen abgebildet werden, wobei das ab einem gewissen Punkt durchaus inperformant wird ^^
LG Kai
Danke für deinen Artikel, sehr interessant.
Ich finde es sollte jedoch nicht unerwähnt bleiben, dass Microsoft (wen wundert es) auch hier Daten sammelt:
https://learn.microsoft.com/de-de/powershell/module/microsoft.powershell.core/about/about_telemetry?view=powershell-7.5
VG Andreas
> Warum gibt es solche Flags eigentlich nicht in echo?
naja, mit tput kann man sich das schon selbst basteln:
die Farben z.B. in die .bashrc eingebaut und schon wird echo nach Belieben farbig ohne komplizierte Ansi-Codes. Geht noch mehr, z.B. fetten oder unterstrichenen Text, u.ä.
s. https://linuxcommand.org/lc3_adv_tput.php
PowerShell auf Linux zu verwenden, weil man aus der Windows-Welt kommt, ist ähnlich makaber wie Bash über Cygwin auf Windows zu nutzen, weil man bei Linux zu Hause ist. Man muss beides lernen, wenn man mit beiden Systemen zu tun hat, und stets das nutzen, was auch für das jeweilige System zugeschnitten ist: PowerShell auf Windows, Bash auf Linux.
Ich finde das Konzept von PowerShell sehr eingrenzend: Bash führt echte Binarys aus und ist easy erweiterbar, solltest du es brauchen: Einfach neue Binarys verfügbar machen. Jedes installierte Programm kann im Scripting verwendet werden, denn dessen Ausgaben sind direkt verwend- und von jeder anderen installierten Binary interpretierbar, denn das ist alles mehr oder minder simpler Text.
PowerShell führt nur mehr Windows-spezifischen Code aus, denn ein Commandlet ist im Grunde PowerShell- oder .NET-Code, das die Argumente interpretiert und "Objekte" zurüçkliefert. Willst du das erweitern, musst du selbst .NET programmieren. Weil PowerShell-fremde Programme keine Objekte im Sinne PowerShells zurückliefern, stehst du sehr schnell vor der Mammutaufgabe, Ausgaben, die nicht PowerShell-konform sind, mit mehr PowerShell PowerShell-konform zu machen. Erstmal gewusst wie!
Im Allgemeinen kann man sagen, dass PowerShell einfach die Mentalität von Microsoft fortsetzt: Embrace, Extend, Exterminate. PowerShell nahm sich die Kommandozeile, wie sie Linux-Admins bekannt ist und älteren Windows-Leuten zu Zeiten von Batch (Embrace), erweitert sie um Ausgaben nicht als Text, sondern als Objekte, die selbst nur schwer erweiterbar sind, ohne dass Microsoft-eigene Technologien dazu verwendet werden (Extend), und biegt damit das Verständnis der Funktionsweise von Shells um, die alte Art durch Cross-Platform-Verfügbarkeit als obsolet deklarierend (Exterminate).
An einem Open Source-PowerShell ist nix Open bis auf den Code. Die Konzepte, die es einführt, sind durchaus als Vendor-Lock-In zu verstehen und dienen der Annäherung an das, was Microsoft für richtig hält; sie sind einfach absolut nicht kompatibel mit allem, was sonst auf Nicht-Windows-Systemen läuft. Deshalb rate ich dringend von PowerShell auf Nicht-Windows ab.
Niemals hätte ich es so gut auf den Punkt bringen können wie du, aber genau dieses Unbehagen habe ich auch gegenüber der Powershell außerhalb von Windows.
Mal abgesehen davon, das mir diese ewig langen Eingaben für eine Nutzung in der Shell viel zu unpraktisch sind, ist mir Begrenzung auf MS-Objekte viel zu eng. Als Skriptsprache, um damit in Windows zu arbeiten, meinetwegen. Aber als Shell- und/oder Skriptsprache in Linux für mich undenkbar.
Sie können auch in Powershell normale Binaries ausführen und deren "stdout" einlesen und verarbeiten. Sie müssen keine Objekte durch die Pipe schieben, es macht aber in vielen Kontexten einfach Sinn mit Objekten zu arbeiten, weil das spezifischer und weniger fehleranfällig ist. Es ist einfacher bestimmte Datenstrukturen anhand spezifischer Properties zu sortieren, zu filtern, neu zusammenzubinden usw..
"mein text".split(" ") | select -last 1 => "text"
Das alles geht übrigens seit fast 20 Jahren! o) Powershell ist nichts "neues", die Shell und die Möglichkeiten entwickeln sich ständig weiter und sind seit Windows-XP ein fester Bestandteil der IT-Welt. Ja, Windows-XP.. das ist lange her. o)
Will man Powershell erweitern, muss man auch kein .Net-Code schreiben, inkludieren Sie einfach Ihre eigenen PS Funktionen oder Klassen. Diese können Sie in Powershell schreiben oder auch in .Net Code, aber selbst "inline", also mitten im Powershell-Code können Sie .Net-Code "reinpfeffern" - und das muss nicht einmal kompiliert werden. Das ist doch mal ziemlich knorke, oder? o)
Powershell ist der Bash m.M. weit überlegen, alles zusätzliche an Funktionalität gegenüber der Bash ist ein "Kann" und kein "Muss", daher kann man sich eigentlich kaum beschweren. Man kann auch Text auf der aktuellen Eingabezeile mit der Tastatur markieren, ausschneiden und wieder einfügen, sehr praktisch und alles ganz ohne Kopfstände (manchmal sind es ja die einfachen Dinge im Leben.. o).
Da Powershell sich auch als richtige Programmiersprache mit Klassen und Vererbung usw. eignet, sind die Vorteile vielleicht nur den Admins mit Programmiererfahrung sofort ersichtlich. Man arbeitet schon lieber mit Parametern die Namen haben, mit einem automatischen Argument-Parser, mit Variablen die einen Typ haben, mit einem XML oder JSON-Parser, mit Klassen, Objekten, Autovervollständigung, Debugging, Exceptions usw. als mit dem, was Bash in dieser Hinsicht anbietet - praktisch nichts.
Es gibt einen Nachteil von Powershell, sie startet nicht so schnell wie ein CMD Prompt oder eine Bash. In einer Automation die einigermaßen schnell gehen soll (sagen wir mal eine Lampe ein/ausschalten), ist der Aufruf eines Powershell-Scripts unter Umständen keine gute Wahl, es gibt aber Speedup-Tricks.
Sich daran zu stören, dass Powershell von Microsoft kommt, kann man machen, die Technik deswegen abzulehnen ist aber vermutlich nicht sonderlich sinnvoll. Powershell ist einfach eine Fortführung, eine Weiterentwicklung, eine moderne Technik die das Leben einfacher machen kann. Man muss sich damit natürlich auch ein bisschen auseinandersetzen und lernwillig sein. Ich denke mal, eine gewisse "Ablehnung" lässt sich auch durch Unwissen oder zumindest viel Halbwissen erklären. Was der Bauer nicht kennt, richtig? o)
Die guten Lösungen unter Linux, die sind ja oft von großen Firmen in das System gekommen. Ich sage mal Samba, RDP, SystemD, SELinux, diverse Datenbanken, Anwendungen und Browser etc.. Das sind alles (Weiter)-Entwicklungen von kommerziellen Unternehmen, die darauf angewiesen sind, dass das Betriebssystem "abliefert". Ob der Linux-Kernel selbst nicht auch kommerziell ist, kann man in einer ruhigen Minute auch nochmal überlegen. Herr Torwalds kassiert glaube ich 1.5 Millionen Dollar pro Jahr.. mhh, das ist schon ordentlich! o)
Powershell ist auch in der Lage GUIs, also Fenster und Buttons und richtige Anwendungen zu "rendern", weil es auf die .NET-Forms Zugriff hat. Es beherrscht Event-Handling für bspw. Filesystem-Watcher, sie kann das ganze Betriebssystem über eine einheitliche Schnittstelle administrieren, vom Anlegen einer VM mit 2 virtuellen Festplatten bis zum einfachen "Cron" Job. Das können Sie alles mit PS erledigen. Sie können mit PS auch Remote-Systeme verwalten oder in Azure ein paar VMs anlegen und das auch noch parallelisiert, weil sie mit PS mehrere Threads und Prozesse gleichzeitig abarbeiten können. Über sogenannte "PSProvider" haben Sie zudem administrativen Zugriff auf "sonstige Datenbestände", also bspw. Dinge wie die Registry oder die Crypto-Zertifikate des Systems und das immer über die gleichen Befehle als wären Sie im Filesystem unterwegs, nur der Kontext ändert sich. Das ist einfach fantastisch, das ist praktisch ein Software-Architekten-Wet-Dream. o)
Powershell ist viel mehr als eine Shell wie "Bash", es ist eine einheitliche Schnittstelle für praktisch alles. Vom 3 Zeiler Script bis zum Deployment von virtuellen Maschinen und Containern in der Cloud. Die Lesbarkeit und nachhaltige Wartbarkeit ist durch die sprechende Syntax auch ein viel besser. Schlecht lesbare, kryptische Einzeiler in Bash, die sind sicher ganz nett, aber sowas hat in einer professionellen Umgebung, in der Code von vielen Leuten gelesen, verstanden und konkret geändert werden muss, nicht viel verloren.
Ich schreibe übrigens auch Bash-Scripte, aber beispielsweise bei der Verwendung von Arrays oder wenn es um "Parameter-" bzw. "Variable Expansion" geht, ist man mit Bash-Scripting ganz schnell wieder in den 80ern angekommen (gefühlt) und dann bereut man auch schnell, das Script in Bash angefangen zu haben. Das gleiche gilt übrigens auch für die *.bat Batch Dateien unter Windows, die machen auch nur bis zu 10 Zeilen Spass (oder Sinn), danach geht das Gezerre sofort ganz heftig los.
Linux hat meiner Meinung viel zu wenige Standards, die die Plattform allgemein nach vorne bringen. Also, vielleicht überdenken Sie Ihre Herangehensweise noch einmal und "embracen" den Fortschritt ein bisschen? Zumindest das krasse Konzept hinter "Powershell", das kann man doch mal würdigen? o)
Powershell ist ein Bindemittel zwischen User, Terminal, Maschine, Scripten, Daten, Netzwerk, Rechenzentrum, Administration, Automatisierung und bietet einen nahezu vollständigen Zugriff auf praktisch alle Funktionen des Betriebsystems (unter Windows zumindest). Powershell kann auch völlig transparent und ohne "mounten" auf Ordner und Dateien im Netzwerk über UNC-Pfade zugreifen, so wie man das unter Windows von allen Anwendungen gewohnt ist. Leider geht das unter Linux auch mit Powershell nicht, denn die Filesystem-Ebene unter Linux abstrahiert keine Netzwerk-Zugriffe (automount muss man vorbereiten und geht auch wieder über lokale mountpoints, ist also kein Äquivalent).
Ich hoffe das gibt noch ein bisschen "Horizont" auf das Thema.
Gruß und Danke! o)
ls -l | sort --numeric --key 5 | tail -3 | awk '{print $9}'
wie wärs mit
ls -Sr | tail -n3
scheint mir um einiges einfacher und leserlicher als die PowerShell Variante
Die drei größten Dateien - das ist auch in der Unix-Shell gar nicht "frickelig"
$ls -S|head -3
Schon viel kürzer und die Schrift nutzt sich nicht so schnell auf den Tasten ab, was ein Beitrag zur Nachhaltigkeit ist :-)