AA_123rf-8294717_ariwasabi_123RF.jpg

© ariwasabi, 123RF

Windows Powershell und Bash im Vergleich

Ungleich entwickelt

Bash und Powershell sind Verwandte, aber wie in jeder großen Familie weisen die Zweige des Stammbaums manchmal sehr unterschiedliche Formen auf.

Seit unserem letzten Blick auf die Kommandozeilen unter Windows und Linux sind einige Jahre ins Land gegangen [1] – es ist an der Zeit, zu schauen, wie sich die beiden Kontrahenten in einem halben Jahrzehnt entwickelt haben. Ein Vergleich der Windows Powershell und der Bash zeigt, wer in Sachen modernes Skripten die Nase vorn hat.

Die Windows Powershell war 2006 unter Windows Vista ein kompletter Neuanfang für Microsofts Kommandozeile (siehe Kasten "Neuanfang"). Die Bash unter Linux dagegen stand seit jeher im Mittelpunkt des Systems (siehe Kasten "Bewährtes"). Kontinuierlich entwickelten die Beteiligten an dem Projekt die Schnittstelle weiter. Es stellt sich dabei die Frage: Ist die Bash gereift und vermag sich mit neuen Ansätzen zu messen, oder trägt sie eher schwer an ihrem Erbe?

Neuanfang

Mit Windows wollte Microsoft zeigen, dass eine grafische Oberfläche zum Bedienen des Computers ausreicht. Für eine schmucklose Shell war einfach kein Platz, und so fristete die Kommandozeile über Jahrzehnte ein Dasein in der Nische.

Trotz aller Vorsätze brauchte es zum Verwalten des Systems aber Skripte. Daher begann unter Windows ein regelrechter Wildwuchs an Interpreter-Sprachen. Über die Jahre entstanden der Windows Scripting Host (WSH), das Windows Management Interface (WMI), HTML Applications (HTA), Active Directory Services Interface (ADSI) und Visual Basic Script (VBS).

Mit Windows Vista stellte Microsoft das System komplett auf eine neue Grundlage. Desktop- und Server-Ausgabe teilten sich die gleiche Code-Basis. Die Entwickler überarbeiteten auch die Struktur der Systemarchitektur und legten alles auf wiederverwendbare Objekte aus. Das .NET-Framework sollte die einheitliche Basis für moderne Anwendungen bilden und quasi wie bei Lego die Bausteine für andere Programme liefern. Ein Interpreter sollte auf die Systembibliothek zugreifen dürfen.

Die neue Shell sollte also das, was moderne Interpreter wie Python und Ruby unter Linux längst draufhatten, nun auch unter Windows einführen. Die Powershell arbeitet daher objektorientiert. Sie kann die Ausgaben eines Kommandos in einer Pipe an ein anderes Kommando weitergeben, und es besteht die Möglichkeit, die .NET-Komponenten einzubinden. Aus der Perspektive moderner Skriptsprachen war das zunächst kein Novum, für Microsoft aber stellte es einen großen Schritt hin zur professionellen Administration des Systems dar.

Seit 2006 hat das Unternehmen vier Generationen der Powershell auf die Welt losgelassen. Windows 7 enthält die Powershell 2.0, Windows 8 die Powershell 3.0 mit zahlreichen Neuerungen. Die aktuelle Version 4.0 entstand für Windows 8.1 und kommt in Kombination mit dem .NET-Framework 4.5.1 als Update auch unter Windows 7 und Windows 8 ins System.

Bewährtes

Die Entwicklung der Bash unter Linux erfolgte recht gradlinig: Gerade einmal 111 Neuerungen flossen seit unserem letzten Vergleich 2007 in die Bash ein [2], der größte Teil davon beim Sprung von der Version 3.2 zur Version 4.0 im Jahr 2009. Die geringen Änderungen bis zur aktuellen Version 4.2 zeigen, dass die Bash recht ausgereift ist.

Knapp die Hälfte (18 von 39) aller eingebauten Funktionen der Bash stammen aus der Bourne Shell. Die Funktionen cd und test zählen sicher zu den häufigsten Aufrufen, aber auch zu den echten Fossilien unter den Kommandos. Die andere Hälfte der Funktionen, darunter echo und read kamen erst in der Bourne Again Shell Bash dazu. Sie dienen alltäglichen Aufgaben; Spezielleres überlässt die Bash anderen Programmen.

Aufgabenteilung gehört ja bekanntlich zum Konzept von Linux. Die Login-Shell hat eher die Funktion einer Kommandozentrale für die vielen spezialisierten Programme. So zählen knapp 100 Programme zu den GNU Coreutils, einer Sammlung, die so gut wie jeder Linux-Distribution beiliegt [3].

Vergleich der Konzepte

Zu den wichtigsten Eigenschaften einer Skriptsprache gehört das Verknüpfen zweier Kommandos. Das setzt voraus, dass ein Kommando die Ausgaben eines anderen erhält, versteht und zur gewünschten Ausgabe aufbereitet. Die Bash nutzt in der Regel reinen Text als Ein- und Ausgabe. So liefert der folgende Aufruf die Größe und den Namen der größten drei Dateien im Verzeichnis /var/log:

$ ls -l /var/log | sed 's/ \+/,/g' | cut -d',' -f 5,9 | sort -g | tail -3
267453,kern.log
443742,kern.log.1
584584,lastlog

Bei der Windows Powershell sind alle Ein- und Ausgaben Objekte. Es wandern also ganze Datenstrukturen von Kommando zu Kommando. Das setzt voraus, dass sich die Objekte an bestimmte Vorgaben halten. Um eine ähnliche Ausgabe wie mit der oben gezeigten Pipe unter Windows zu erhalten, brauchen Sie das Wissen um die Eigenschaften der entsprechenden Objekte:

PS> Get-ChildItem -Directory | Sort-Object -Property Length | Select-Object Length,Name -Last 3
   Length Name
   ------ ----
 597379 Manual.pdf
 5715026 Applications.in.Ruby.pdf
 27318109 AnnualCatalogue_de-EU.pdf

Dass bei der Bash die Ausgaben als Text vorliegen, erleichtert freilich das Anpassen der Optionen zum Verarbeiten des nächsten Programms. Meist läuft es dabei auf Ausprobieren hinaus – das klappt bei der Powershell nur eingeschränkt.

Im Beispiel brauchen Sie die Eigenschaften Length und Name. Intuitiv hätten Sie vielleicht als Eigenschaft für die Dateigröße auf Size getippt, statt auf Length. Um die Eigenschaften eines Objekts also sicher zu kennen, bleibt oft nur der Griff zur Dokumentation.

Dabei gestaltet sich der obige Aufruf aus der Powershell 3.0 schon einfacher als aus den Vorgängerversionen: Anfangs kannte das Cmdlet Get-ChildItem die Option -Directory noch nicht. Daher galt es, ein zusätzliches Cmdlet zum Ausfiltern von Verzeichnissen – Where-Object {-not $_.PSIsContainer} – in die Pipe einzubauen, denn nur Verzeichnisse haben die Eigenschaft PSIsContainer.

Der Unterschied bei der Ein- und Ausgabe von Daten ist nur einer von vielen zwischen Bash und Powershell, jedoch springt er sofort ins Auge. Grundsätzlich unterscheiden sich die Konzepte der beiden Shells: Die Bash zielt auf Arbeitsteilung ab, die Powershell orientiert sich an den Aufgaben. Das verstärkte sich noch in den Versionen 3.0 und 4.0.

Steile Lernkurve

Die Bash kommt mit knapp 40 internen Funktionen und 100 Hilfsprogrammen zurecht. Die Powershell 4.0 verfügt bereits über 299 eingebaute Cmdlets. In der Version 2.0 (Windows 7) waren es noch 251. Jedes Cmdlet verfügt über Optionen, von denen mit jeder Version der Powershell neue hinzukommen.

So verfügt das Cmdlet Get-Content ab Version 3.0 (Windows 8) nun über die Option -Tail Anzahl, welche die Entwickler augenscheinlich dem Unix-Programm Tail entlehnt haben. Für einen Einstieg in die Neuerungen der Powershell helfen kurze Übersichten von Microsoft [4].

Die Cmdlets erscheinen im Vergleich zu den Builtins der Bash als Miniprogramme. Dies spüren Sie immer dann, wenn die letzte Verwendung eines Cmdlet schon etwas zurückliegt. Dann braucht es meist einen Blick in die Referenz, um die korrekten Parameter und Optionen zu finden. Im Gegenzug erledigen die Cmdlets komplexere Aufgaben in einem Aufruf. Um etwa alle Links in der Webseite linux-user.de auszugeben, genügt ab Powershell 3.0 der Aufruf aus Listing 1.

Listing 1

PS> (Invoke-WebRequest http://www.linux-user.de/).links
innerHTML : <IMG border=0 alt=logoOL.gif src="http://www.linux-user.de/pix/logoOL.gif" width=140 height=62>
innerText :
outerHTML : <A href="/"><IMG border=0 alt=logoOL.gif src="http://www.linux-user.de/pix/logoOL.gif" width=140
            height=62></A>
outerText :
tagName   : A
href      : /

Manchmal erscheint dieses Orientieren an Aufgaben recht einseitig, und es macht einige Aufgaben etwas umständlich. Um ein Passwort zu generieren, genügt es unter der Bash, den Datei-Deskriptor für den Zufallsgenerator auszulesen und ein wenig aufzubereiten (Listing 2).

Listing 2

$  echo $(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c10)
Kc-TUGC8cd

Um unter der Powershell 3.0 Ähnliches zu erreichen, besteht eine Möglichkeit darin, eine Systembibliothek aus dem .NET-Framework nachzuladen und ein Modul daraus zu nutzen: Es gibt im Assembly System.Web das Modul Security.Membership und dort die Funktion GeneratePassword (Listing 3).

Listing 3

PS> $Assembly = Add-Type -AssemblyName System.Web
PS> [System.Web.Security.Membership]::GeneratePassword(10,3)
lGv%.ua]Wl

Bei der Powershell stellt sich die Frage: Wie kommen Sie an die Information, welche Objekte welche Methoden anbieten, und in welcher der mehreren Tausend Systembibliotheken versteckt sich eine Funktion GeneratePassword? Hinter der Antwort steckt Fleißarbeit: Es erfordert ein Studium der extrem umfangreichen Referenz zum .NET-Framework [5], um dessen Möglichkeiten richtig auszureizen.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

Kommentare
Ziemlich viel Falsches im Artikel
Jo (unangemeldet), Donnerstag, 27. Oktober 2016 22:32:26
Ein/Ausklappen

"Trotz aller Vorsätze brauchte es zum Verwalten des Systems aber Skripte. Daher begann unter Windows ein regelrechter Wildwuchs an Interpreter-Sprachen. Über die Jahre entstanden der Windows Scripting Host (WSH), das Windows Management Interface (WMI), HTML Applications (HTA), Active Directory Services Interface (ADSI) und Visual Basic Script (VBS)."

Äpfel. Birnen. Seit der Verfügbarkeit des WSH 1998 haben NT-basierten Windows-Versionen Script-Interpreter für genau zwei Sprachen vorinstalliert: Visual Basic Script und Java Script. WMI und ADSI sind APIs, die es auch mit der PowerShell nach wie vor gibt und natürlich auch von der PowerShell verwendet werden. HTA und WSH sind nur Hosts für Script-Sprachen.

"Mit Windows Vista stellte Microsoft das System komplett auf eine neue Grundlage. Desktop- und Server-Ausgabe teilten sich die gleiche Code-Basis."

Desktop- und Server-Version haben schon immer denselben Kernel genutzt. Microsoft hat mit Vista lediglich das Datum der Releases von Desktop und Server angeglichen. Natürlich hat Microsoft mit Vista den Kernel auch weiterentwickelt, aber "eine neue Grundlage" ist schon weit hergeholt.

"Die Entwickler überarbeiteten auch die Struktur der Systemarchitektur und legten alles auf wiederverwendbare Objekte aus."

Das .NET Framework gibt es seit 2002, COM noch deutlich länger. Vista hat dabei keine dramatischen Neuerungen gebracht.

"Das .NET-Framework sollte die einheitliche Basis für moderne Anwendungen bilden und quasi wie bei Lego die Bausteine für andere Programme liefern. Ein Interpreter sollte auf die Systembibliothek zugreifen dürfen."

Auch die "alten" Interpeter für VBS und JS können auf Systembibliotheken zugreifen, sofern sie COM-kompatibel sind. Die PowerShell eben auf .NET-Bibliotheken. Die PowerShell kann nur sehr indirekt auf Systembibliotheken des Win32-APIs zugreifen (über P/Invoke).

"Die neue Shell sollte also das, was moderne Interpreter wie Python und Ruby unter Linux längst draufhatten, nun auch unter Windows einführen."

Auch VBS und JS sind mächtige Scriptsprachen, die allerdings nicht auf das neue API, das .NET Framework zugreifen können. Was Microsoft bis dahin gefehlt hat, war eine leistungsfähige Shell.

"Zu den wichtigsten Eigenschaften einer Skriptsprache gehört das Verknüpfen zweier Kommandos."

Nein, das ist die Eigenschaft einer leistungsfähigen Shell.

"Dass bei der Bash die Ausgaben als Text vorliegen, erleichtert freilich das Anpassen der Optionen zum Verarbeiten des nächsten Programms. Meist läuft es dabei auf Ausprobieren hinaus – das klappt bei der Powershell nur eingeschränkt.
[...]
Um die Eigenschaften eines Objekts also sicher zu kennen, bleibt oft nur der Griff zur Dokumentation."

Das ist falsch. .NET-Objekte (was die ausgegebenen PowerShell-Objekte im Wesentlichen sind) sind selbstbeschreibend. Beispiel:

Get-Process | Get-Member

zeigt die ausgegebenen Eigenschaften ohne Griff zur Dokumentation an. Darüberhinaus ist der Name einer Eigenschaft auch meistens schon in der Ausgabe des Cmdlets zu erkennen.

"Um in der Bash herauszufinden, welches Kommando weiterhilft, genügt ein Aufruf von apropos Stichwort. [...] Bei der Powershell gibt es zwar ein Cmdlet Get-Help, oft hilft das jedoch insbesondere Einsteigern beim Umgang mit komplexen Objekten nicht weiter. Microsoft hat der Powershell daher eine kleine Entwicklungsumgebung mitgegeben, die nebenbei eine interaktive Übersicht über die Befehle enthält."

Man kann die ISE zwar dafür nutzen, bei der Menge von Kommandos in einer aktuellen PowerShell aus meiner Sicht ziemlich unbrauchbar; auf meinem System (Windows 8.1) gibt es über 2.400 Cmdlets und Funktionen. Schlüssel für das Auffinden des richtigen Kommandos ist eine konsistente Namenskonvention (inspiriert von VMS DCL, der PowerShell-Architekt Jeffrey Snover war zuvor bei Digital) und das Cmdlet Get-Command, mit dem sich Kommandos über Wildcards suchen lassen.

"Für viele Admins unter Linux stellt sich die Frage einer Entwicklungsumgebung für Skripte gar nicht: Leistungsfähige Editoren wie Vim oder Emacs verfügen über zahlreiche Funktionen, die das Scripting erleichtern, wie etwa Syntax-Highlighting, komplexe Funktionen zum Navigieren in Skripten und eingebaute Makrosprachen. Derartige Editoren zählten bislang unter Windows so nicht zum Standardumfang."

Diese Aussage überrascht mich jetzt, nachdem der vorhergehende Absatz die zum Lieferumfang gehörende Entwicklungsumgebung ISE erwähnt, die natürlich Syntax-Highlighting bietet.

Alles in allem enthält der Artikel mehr Falsches als Richtiges. Die PowerShell hat natürlich auch Schwächen, die der Artikel aber alle auslässt.


Bewertung: 246 Punkte bei 48 Stimmen.
Den Beitrag bewerten: Gut / Schlecht
-
Re: Ziemlich viel Falsches im Artikel
Andreas Bohle, Donnerstag, 19. Januar 2017 14:24:36
Ein/Ausklappen

Hallo Jo,

vielen Dank für Dein umfassendes Feedback. Vielleicht kannst Du, wenn Du das liest, Kontakt zur Redaktion aufnehmen.

Beste Grüße
Andreas Bohle


Bewertung: 241 Punkte bei 40 Stimmen.
Den Beitrag bewerten: Gut / Schlecht
Kleiner Fehler
Marcus Nasarek, Samstag, 08. März 2014 14:25:00
Ein/Ausklappen

Im Powershell-Kommando für die Anzeige der drei größten Dateien im Verzeichnis hat sich ein Fehler eingeschlichen. Mit dem Paramter -Directory kann man zwar Verzeichnisse filtern, eigentlich sollten aber Dateien gefiltert werden. Der korrekte Parameter zum Filtern von Dateien lautet -File. Der Powershell-Aufruf zum Anzeigen der drei größten Dateien im aktuellen Verzeichnis lautet daher:

Get-ChildItem -File | Sort-Object -Property Length | Select-Object Length,Name -Last 3



Bewertung: 308 Punkte bei 126 Stimmen.
Den Beitrag bewerten: Gut / Schlecht

Infos zur Publikation

LU 12/2017: Perfekte Videos

Digitale Ausgabe: Preis € 5,95
(inkl. 19% MwSt.)

LinuxUser erscheint monatlich und kostet 5,95 Euro (mit DVD 8,50 Euro). Weitere Infos zum Heft finden Sie auf der Homepage.

Das Jahresabo kostet ab 86,70 Euro. Details dazu finden Sie im Computec-Shop. Im Probeabo erhalten Sie zudem drei Ausgaben zum reduzierten Preis.

Bei Google Play finden Sie digitale Ausgaben für Tablet & Smartphone.

HINWEIS ZU PAYPAL: Die Zahlung ist ohne eigenes Paypal-Konto ganz einfach per Kreditkarte oder Lastschrift möglich!

Stellenmarkt

Aktuelle Fragen

Data Security
jesse james, 18.12.2017 18:04, 1 Antworten
Hallo zusammen! Ich bin PC- Neuling. Ich habe gehört, dass man für Linux keine Firewall und ke...
EasyBCD/NeoGrub
Wolfgang Conrad, 17.12.2017 11:40, 0 Antworten
Hallo zusammen, benutze unter Windows 7 den EasyBCD bzw. NEOgrub, um LinuxMint aus einer ISO Dat...
Huawei
Pit Hampelmann, 13.12.2017 11:35, 2 Antworten
Welches Smartphone ist für euch momentan das beste? Sehe ja die Huawei gerade ganz weit vorne. Bi...
Fernstudium Informatik
Joe Cole, 12.12.2017 10:36, 2 Antworten
Hallo! habe früher als ich 13 Jahre angefangen mit HTML und später Java zu programmieren. Weit...
Installation Linux mint auf stick
Reiner Schulz, 10.12.2017 17:34, 3 Antworten
Hallo, ich hab ein ISO-image mit Linux Mint auf einem Stick untergebracht Jetzt kann ich auch...