Website-Suche

Achten Sie auf diese 6 inkonsistenten Linux-Befehle, besonders wenn Sie ein anderes Betriebssystem verwenden


Jeder Befehl, den Sie in einem Linux-Terminal ausführen, verhält sich auf allen Systemen gleich, oder? Falsch. Obwohl Linux-Befehle oft sehr portabel sind, kann es Ausnahmen geben.

Einzelne Befehle können verschiedene Versionen haben, wie zum Beispiel GNUMs find und das entsprechende BSD-Programm. Programme können auch je nach Version von Unix unterschiedlich sein, wie Solaris, IBM AIX und macOS, oder sogar je nach Distribution, wie BusyBox von Alpine Linux.

stat

Ein niedrigstufiges Werkzeug mit vielen plattformbedingten Inkonsistenzen

Das stat-Dienstprogramm zeigt Informationen über eine Datei an, ein bisschen wie ein Low-Level-ls:

Selbst seine Standardnutzung kann jedoch auf verschiedenen Systemen deutlich unterschiedliche Ergebnisse liefern:

Aber das ist nur der Anfang. Die Optionen -f, -c und -t von GNU stat werden bei BSD-Varianten entweder nicht unterstützt oder verhalten sich ganz anders. Zum Beispiel kann man mit der GNU-Version, um die Blockgröße anzuzeigen, diesen Befehl ausführen:

stat -c %s filename

Bei BSD stat müssen Sie jedoch eine andere Option und eine andere Formatzeichenfolge verwenden:

stat -f %b filename

Es gibt auch einen entscheidenden Unterschied, den Sie bei allen GNU-Tools finden werden: die Unterstützung für lange Optionen, einschließlich des allgegenwärtigen --help und --version. Diese Optionen sind entscheidend, um etwas über einen Befehl zu lernen, ohne das Handbuch zu Rate zu ziehen, aber die BSD-Äquivalente haben sie oft nicht.

find

Dieses Werkzeug ist bereits komplex, aber die GNU-Version hat einige nette Bequemlichkeiten

Versionen dieses populären Programms unterscheiden sich so stark, dass sie sich nicht einmal auf die Terminologie einigen können. BSDs find spricht von „Primaries“, während die GNU-Version stattdessen von „Tests“ und „Actions“ spricht.

Bei einer großen Anzahl von Optionen ist es keine Überraschung, dass verschiedene Versionen von find unterschiedliche Verhaltensweisen unterstützen. Ein wichtiges Beispiel ist die -printf-Option von GNU, die es Ihnen ermöglicht, die Ausgabe von find anzupassen:

find . -printf "%f\n"

Die BSD-Version unterstützt die -printf-Option überhaupt nicht, daher möchten Sie deren Ausgabe möglicherweise an stat weiterleiten - wobei Sie auch deren Unterschiede berücksichtigen sollten.

Einige Inkompatibilitäten sind jedoch weitaus weniger bedeutend. Zum Beispiel unterstützt Version von GNU von find die -d-Option von BSD, die find dazu bringt, eine Tiefensuche durchzuführen. Es wird jedoch dabei eine höfliche Warnmeldung ausgegeben:

Die GNU-Version von find erlaubt es auch, das Pfadargument wegzulassen, in welchem Fall es standardmäßig auf das aktuelle Verzeichnis gesetzt wird. Dieses Verhalten ist im POSIX-Standard nicht definiert - BSD find wird die Nutzungshinweise anzeigen und einen Fehler zurückgeben - aber es ist sicherlich praktisch.

top

Das fühlt sich fast wie ein völlig anderes Werkzeug an

Natürlich wird eine Liste der auf Ihrem System laufenden Prozesse von einer Umgebung zur nächsten stark unterschiedlich sein. Aber auch die Daten, die top anzeigt, und das Format, in dem sie angezeigt werden, können radikal unterschiedlich sein.

Zunächst einmal ist die Zusammenfassungsinformation von BSD am oberen Bildschirmrand ausführlicher und enthält zusätzliche Details wie Netzwerk- und Festplattenstatistiken.

Während die GNU-Version den Speicherprozentsatz einschließt, zeigt BSD einen absoluten Wert an. Es gibt viele andere Unterschiede in den Standardspalten, insbesondere in ihrer Reihenfolge.

Da Sie top nur in einer interaktiven Sitzung verwenden werden, sind Unterschiede weniger bedeutsam als bei anderen Befehlen, auf die Sie in einem Skript angewiesen sein könnten.

sed

BSD erzwingt eine etwas umständliche Syntax

Der Stream-Editor sed ist ein flexibles Werkzeug, mit dem Sie Eingaben mithilfe regulärer Ausdrücke transformieren können. Eine seiner nützlichsten Funktionen ist die Option -i, mit der Sie eine Datei direkt bearbeiten können:

sed -i 's/foo/bar/g' filename

Aber auf einem BSD-System wird sed für denselben Befehl eine sehr verwirrende Fehlermeldung anzeigen:

Dies liegt daran, dass BSDs Umgang mit der -i-Option subtil anders ist und ein Argument erwartet, das die Erweiterung angibt, mit der eine Sicherungsdatei gespeichert werden soll:

sed -i .bak 's/foo/bar/g' filename

Obwohl Sie dieses Verhalten mit einer leeren Erweiterung ganz umgehen können, müssen Sie BSD sed immer ein Argument geben, um den ursprünglichen Fehler zu vermeiden:

sed -i '' 's/foo/bar/g' filename

grep

Besser als zuvor, aber BSD-Nutzer verpassen immer noch etwas

Mit einer riesigen Bandbreite an Einsatzmöglichkeiten ist grep ein unverzichtbares Werkzeug in jedem Linux-Toolkit. Historisch gesehen war es jedoch eine Quelle von Portabilitätsproblemen, die auf Unterschiede in der zugrunde liegenden regulären Ausdrucks-Engine zurückzuführen sind. Auf GNU-Systemen ist der Standard BRE (basic), während macOS zuvor eine strikte POSIX-Syntax bevorzugt hat.

Glücklicherweise sind diese Unterschiede heute weniger ausgeprägt, und auf einer modernen Version von macOS wirbt grep damit, "BSD grep, GNU kompatibel" zu sein.

Aber eine große Diskrepanz bleibt bestehen: die Unterstützung für Perl-kompatible reguläre Ausdrücke (PCRE). Mit der Option -P erlaubt GNU grep die Verwendung der flexibleren Syntax, die vom Regex-Parser von Perl eingeführt wurde:

grep -P '\d+' numbers.txt

Mit erweiterten Zeichenklassen, nicht-gierigen Übereinstimmungen und benannten Teilmustern bietet PCRE erhebliche Vorteile, aber seien Sie vorsichtig, sich auf sie zu verlassen, und stellen Sie sicher, dass Sie wissen, ob Sie sie verwenden können oder nicht.






cp

Sogar die grundlegendsten Befehle können unzuverlässig sein

Man könnte erwarten, dass ein einfacher Befehl wie cp konsistent ist; leider täuscht man sich. Unter Ubuntu, Red Hat oder Debian können Sie die -u-Option verwenden, um eine Quelldatei nur zu kopieren, wenn sie neuer als das Ziel ist:

cp -u ./original ./target

Leider fehlt diese nützliche Option in anderen Versionen, einschließlich derjenigen, die mit macOS gebündelt ist.

Wenn Sie stattdessen die GNU-Versionen dieser Werkzeuge verwenden möchten, können Sie Homebrew verwenden, um coreutils zu installieren.

Die GNU-Version von cp unterstützt sogar eine alternative Methode, mehrere Dateien in ein einzelnes Verzeichnis zu kopieren. Der Standardansatz, der von allen Versionen unterstützt werden sollte, besteht darin, alle Dateien als Parameter anzugeben, wobei der letzte Parameter ein Verzeichnis ist:

cp file1.c file2.c file3.c src

Aber nur die GNU-Version unterstützt eine -t-Option, um die Reihenfolge umzukehren:

cp -t src file1.c file2.c file3.c

Die letztere Form kann bequemer sein, wenn Sie sie eintippen, aber Sie werden den größten Nutzen daraus ziehen, wenn Sie cp in einer Pipeline verwenden:

find . -name '*.c' | xargs cp -t src

Halten Sie sich an das grundlegende POSIX-Verhalten, wenn Ihnen Kompatibilität wichtig ist

Obwohl keines der beiden gängigen Werkzeugsets besser als das andere ist, gibt es bei BSD und GNU erhebliche Unterschiede. Im Allgemeinen halten sich BSD-Werkzeuge eher an den POSIX-Standard, aber die GNU-Erweiterungen - wie lange Optionen und klarere Hilfen - sind in der Regel lohnenswert.

Welche auch immer Sie verwenden, machen Sie sich mit den Unterschieden vertraut und lernen Sie, sie zu erkennen, besonders wenn Sie sich in einer neuen Umgebung zurechtfinden.

Verwandte Artikel