AA_PO-22478_bekas007_123RF.jpg

© bekas007, 123RF

Eingepackt

Mit SHC Bash-Skripte kompilieren

20.02.2014
Der Shell Script Compiler wandelt Skripte in Binärprogramme um. Das schützt vor unbeabsichtigten Veränderungen, birgt aber auch einige Tücken.

Es gibt eine Reihe von Gründen, Programme aller Art zu kompilieren, also auch Skripte. An erster Stelle steht dabei ein Gewinn an Geschwindigkeit beim Ausführen. Weiterhin erzeugen Compiler im Idealfall kleine, portable Programme, die weitgehend unabhängig von demjenigen Rechner laufen, auf dem Sie sie erstellt haben. Weiterhin bietet sich diese Methode an, um die eingesetzten Algorithmen vor unbeabsichtigten Veränderungen zu schützen.

Die beiden ersten Punkte – der Zuwachs an Geschwindigkeit und die Portabilität – stehen beim Shell Script Compiler SHC [1] nicht im Fokus. So benötigen die mit dem SHC übersetzten Programme immer noch die Bash als Interpreter, und ein größeres Tempo stellt sich kaum ein. Dieser Punkt dürfte aber keine große Rolle spielen, da Shell-Skripts ohnehin nicht für zeitkritische Anwendungen taugen.

Dafür schützt das Übersetzen in Binärcode den Quelltext vor den Ambitionen von Anwendern, etwas Gutes vielleicht doch noch ein wenig besser zu machen, um es dann vollkommen zu verhauen. Derzeit ist der SHC das bekannteste freie Werkzeug, um (Bash-)Shell-Skripts in ausführbare Programme zu übersetzen.

Die Arbeitsweise des SHC weist aufgrund dieser Zielsetzung einige Besonderheiten auf. So erfolgt das Kompilieren in zwei Schritten: Zunächst erzeugt SHC aus dem Skript einen ziemlich umfangreichen, sehr speziellen C-Quellcode, den er anschließend mit dem Compiler in ein binäres Programm übersetzt (Abbildung 1).

Abbildung 1: Der SHC arbeitet in zwei Stufen: Zunächst erzeugt er C-Code, den er anschließend mit dem CC kompiliert.

Im ersten Schritt generiert SHC dafür eine Datei mit der Endung .x.c, die er dann mit dem in der Umgebungsvariablen $CC vereinbarten C-Compiler in eine Datei mit der Endung .x übersetzt. Das Umsetzen des Skript-Quelltexts in C-Code basiert auf dem Einsatz eines Arrays, das den Inhalt des Skripts enthält. Beim Übersetzen greift SHC schrittweise auf die (verschlüsselten) Einträge des Arrays zu und bindet sie in das ausführbare Programm ein.

Wie das Bearbeiten des Arrays und das Umsetzen in das binäre Programm im Detail erfolgt, finden Sie ausführlich in einem Blog im Web beschrieben [2]. Die Seite behandelt außerdem das Thema Sicherheit von Passwörtern in Skripten. Zudem diskutiert der Autor auch die Möglichkeiten, mittels SHC erstellte Programme nachträglich wieder zu entschlüsseln.

SHC installieren

Unter Ubuntu und dessen Varianten gestaltet sich die Installation von SHC einfach, da es hier PPAs mit mehr oder weniger aktuellen Versionen gibt.

Unter Arch Linux gilt es, zwei Klippen zu umschiffen: Dort befindet sich das Paket in der aktuellen Version in den Arch User Repositories (AUR), allerdings mit einer falschen Prüfsumme in der Datei PKGBUILD (Listing 1). Die korrekte Checksumme berechnen Sie mit dem Tool sha256sums und fügen sie bei der entsprechenden Abfrage (Listing 2) ein. Das Skript öffnet einen Editor, um Ihnen die erforderliche Änderung zu gestatten.

Weiterhin gehören zum SHC-Paket eigentlich eine Reihe von Testskripten (pru.sh, test.bash), die das Paketmanagement bei Arch Linux voreingestellt nicht einrichtet, obwohl das Original-Archiv sie enthält. Diese dienen zum Überprüfen der korrekten Funktion des SHC. Sie sollten sie daher unbedingt vor dem Einsatz übersetzen und die Ergebnisse untersuchen.

Alternativ gibt es die Möglichkeit, den SHC direkt aus den Quelltexten zu erzeugen und zu installieren. Nach dem Entpacken des Archivs genügt ein einfaches make zum Übersetzen; make install installiert das Programm unter /usr/local/. Das Target make test funktioniert in der Version 3.8.9 nicht mehr. Verwenden Sie stattdessen shc -f test.bash.

Listing 1

source=("http://www.datsi.fi.upm.es/~frosal/sources/${pkgname}-${pkgver}.tgz")
sha256sums=('\textbf{ef7bbf1252c9c791f711782870d00d6f19c42c08e0ee57e9a04d0e2b3d114d40}')

Listing 2

...
( Unsupported package: Potentially dangerous ! )
==> Edit PKGBUILD ? [Y/n] ("A" to abort)
==> ------------------------------------
\textbf{Y}...

Praxis

Für einen ersten Test bietet sich das klassische "Hello World" an, das mit echo "Hello SHC" allerdings einen alternativen Text ausgibt. Lautet die erste Skript-Zeile nicht #! /bin/sh, dann bricht der Befehl shc -f hello.sh mit der Meldung shc: invalid first line in script:... ab. Mit dem Shebang klappt das Übersetzen, mit der Option -v auch kommentiert (Listing 3).

Listing 3

# shc -v -f hello.sh
shc shll=bash
shc [-i]=-c
shc [-x]=exec '%s' "$@"
shc [-l]=
shc opts=
shc: cc  hello.sh.x.c -o hello.sh.x
shc: strip hello.sh.x
shc: chmod go-r hello.sh.x

Der dabei erzeugte Quelltext hello.sh.x.c fällt mit knapp 9 KByte vergleichsweise groß und auf den ersten Blick weitgehend unverständlich aus, beschäftigen sich doch die größten Teile mit der Verschlüsselung des Skripts.

Das ausführbare Programm ist mit 11 KByte auch nicht gerade klein und weist auf unterschiedlichen Plattformen einige Probleme auf: So laufen unter Arch Linux und Ubuntu generierte Programme auf Arch Linux nur dann, wenn Sie sie mit der Option -T erstellt haben. Eigentlich ermöglicht es diese Option, den Ablauf des Programms mit externen Diagnosewerkzeugen wie Strace zu beobachten. Unter Ubuntu dagegen laufen die auf beiden Systemen erzeugten Binaries problemlos.

Shell-Skripte haben einige spezielle Eigenschaften, die der Compiler verstehen und umsetzen muss. So erlaubt es die Bash, dem Skript Argumente zu übergeben, die innerhalb des Skripts als Positionsparameter bereitstehen. Damit kommt SHC problemlos klar, auch dann, wenn Sie über set die Parameter neu zuordnen.

Zu den nächsten wichtigen Punkten, den der Compiler bei Shell-Skripten abklären muss, gehört das Auswerten von Rückgabewerten ("Exit Codes"), die sowohl von internen als auch externen Befehlen stammen. Bei der Bash enthält die Variable $? diesen Wert für den letzten, im Vordergrund ausgeführten Befehl; Sie lesen ihn durch echo $? am Prompt aus. Der SHC unterstützt dies ebenfalls.

Gerade in Shell-Skripten kommen Rückgabewerte in Zusammenhang mit bedingten Verknüpfungen von Befehlen zum Einsatz. Die Bash bietet hier durch Kurzschlusstests ("Short Circuit Tests") sehr viel Komfort: Das doppelte Ampersand (&&) verbindet zwei Befehle, von denen die Shell den zweiten nur dann ausführt, wenn der erste ohne Fehler terminiert – also mit Rückgabewert 0.

Alternativ nutzen Sie die doppelte Pipe (||) zum Verknüpfen. In diesem Fall führt die Shell den folgenden Befehl nur aus, wenn der zuvor stehende mit einem Fehler (Rückgabewert ungleich null) terminiert. Short Circuit Tests stehen in Kombination mit SHC problemlos bereit (Listing 4).

Listing 4

$ true && echo "OK"   # OK
$ false && echo "OK"  # keine Ausgabe
$ true || echo "OK"   # keine Ausgabe
$ false || echo "OK"  # OK
$ true || echo "nö" && echo "ja" # ja
$ true && echo "ja" || echo "nö" # ja

Ein weiteres, manchmal heikles Thema stellen Ein- und Ausgaben dar. Ohne zusätzliche Software bietet die Shell nur sehr begrenzte Möglichkeiten. Dafür funktionieren diese eigentlich immer. Fragen Sie Eingaben mittels Zenity oder der neueren Variante YAD ab (Listing 5), bringt das den SHC nicht aus dem Tritt.

Listing 5

EINGABE=$(yad --entry "eingabe" --editable); yad --entry $EINGABE

In Listing 5 erhält zunächst die Umgebungsvariable EINGABE durch die Abfrage mittels YAD ihren Wert. Der Eingabedialog ist mit der Zeichenkette eingabe vorbelegt. Sie dürfen diese aber verändern, was der Parameter --editable ermöglicht. Anschließend zeigt der zweite Aufruf von YAD den aktuellen Inhalt der Variablen $EINGABE an.

Beim Einsatz externer Programme gilt es zu beachten, dass SHC sie nicht etwa in das binäre Programm einbindet, sondern immer noch wie im Skript aufruft. Das setzt voraus, dass sich diese im Pfad befinden. Das Gleiche gilt für die aufrufende Bash, die ebenfalls unter dem erwarteten Pfad vorhanden sein muss. Alternativ berücksichtigt SHC absolute Pfade beim Ausführen des kompilierten Skripts.

Unter Kontrolle

Sie steuern SHC hauptsächlich über Optionen, deren wichtigste die Tabelle "SHC-Optionen" erläutert. Darüber hinaus wertet SHC zwei Umgebungsvariablen aus: $CC enthält den verwendeten C-Compiler, voreingestellt cc. In diesem Zusammenhang kommt die zweite Variable $CFLAGS zum Einsatz, die die Optionen für den Compiler enthält.

SHC-Optionen

Option Erläuterung
-e Datum Begrenzt die Zeit, in der sich das Programm ausführen lässt bis auf das angegebene Datum. Der Compiler erwartet das Datum in der Form TT/MM/JJJJ. Nach dem Ablauf erscheint eine Warnung.
-m Nachricht Nachricht erscheint zusätzlich nach dem Ablauf der durch -e eingestellten Zeit.
-f Skript Zwingend erforderlich, bezeichnet im Argument das Skript, das SHC übersetzen soll.
-i Shell-Optionen Spezielle Optionen für die Bash.
-x Befehl Das binäre Programm startet das Skript mittels exec, voreingestellt gefolgt von $@ (alle Befehlszeilenoptionen und -argumente).
-l Option Definiert die letzte Befehlszeilenoption, normalerweise -- (was auch voreingestellt ist).
-r Lockert die Einstellungen in Bezug auf die Sicherheit beim Übersetzen, sodass die binären Programme auf anderen Rechnern mit dem gleichen Betriebssystem laufen. Bei Arch Linux ist diese Option derzeit zwingend erforderlich.
-D Aktiviert den Debug-Modus des binären Programms. Das erzeugt eine Menge zusätzlicher Informationen.
-T Ein Programm erstellen, das sich mit Strace oder ähnlichen Tools verfolgen lässt.
-A Zeigt eine kurze Info und beendet SHC, ohne das Skript zu kompilieren.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4 Heftseiten

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

LinuxCommunity kaufen

Einzelne Ausgabe
 
Abonnements
 

Ähnliche Artikel

  • Einführung in die Bash-Programmierung
    Skripte sollen meist wiederkehrende oder lästige Arbeiten automatisieren. Die Standard-Shell Bash stellt Ihnen dazu eine ganze Reige von Funktionen bereit. Dieser Artikel erklärt, wie Sie ihre eigenen Shell-Skripte schreiben.
  • Stromstoß für die Shell
    Shell-Skripte verrichten unter Linux allgegenwärtig ihren Dienst. Mit Bashdiff erhält die Standard-Shell Features, die Sie sonst nur in höheren Programmiersprachen finden.
  • Bash-Skripte prüfen lassen
  • Bash-Skripte sind Programme
    Wer regelmäßig mit der Shell arbeitet, wird leicht zum Programmierer: Schreiben Sie mehrere Shell-Befehle in eine Textdatei und machen diese ausführbar, haben Sie schon Ihr erstes Shell-Skript entwickelt. Die Shell bietet als Programmiersprache aber noch viel mehr.
  • Die Kraft der Muschel
    Microsofts neue PowerShell greift auf die Bibliotheken des .NET-Frameworks zurück und verfügt so über einen riesiger Fundus von Funktionen und Objekten. Ist sie dadurch einer traditionellen Shell wie der Bash überlegen?
Kommentare

Infos zur Publikation

LU 11/2014: VIDEOS BEARBEITEN

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

Mit der Zeitschrift LinuxUser sind Sie als Power-User, Shell-Guru oder Administrator im kleinen Unternehmen monatlich auf dem aktuelle Stand in Sachen Linux und Open Source.

Sie sind sich nicht sicher, ob die Themen Ihnen liegen? Im Probeabo erhalten Sie drei Ausgaben zum reduzierten Preis. Einzelhefte, Abonnements sowie digitale Ausgaben erwerben Sie ganz einfach in unserem Online-Shop.

NEU: DIGITALE AUSGABEN FÜR TABLET & SMARTPHONE

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

Tipp der Woche

Schnell Multi-Boot-Medien mit MultiCD erstellen
Schnell Multi-Boot-Medien mit MultiCD erstellen
Tim Schürmann, 24.06.2014 12:40, 0 Kommentare

Wer mehrere nützliche Live-Systeme auf eine DVD brennen möchte, kommt mit den Startmedienerstellern der Distributionen nicht besonders weit: Diese ...

Aktuelle Fragen

Artikelsuche
Erwin Ruitenberg, 09.10.2014 07:51, 1 Antworten
Ich habe seit einige Jahre ein Dugisub LinuxUser. Dann weiß ich das irgendwann ein bestimmtes Art...
Windows 8 startet nur mit externer Festplatte
Anne La, 10.09.2014 17:25, 4 Antworten
Hallo Leute, also, ich bin auf folgendes Problem gestoßen: Ich habe Ubuntu 14.04 auf meiner...
Videoüberwachung mit Zoneminder
Heinz Becker, 10.08.2014 17:57, 0 Antworten
Hallo, ich habe den ZONEMINDER erfolgreich installiert. Das Bild erscheint jedoch nicht,...
internes Wlan und USB-Wlan-Srick
Gerhard Blobner, 04.08.2014 15:20, 2 Antworten
Hallo Linux-Forum: ich bin ein neuer Linux-User (ca. 25 Jahre Windows) und bin von WIN 8 auf Mint...
Server antwortet mit falschem Namen
oin notna, 21.07.2014 19:13, 1 Antworten
Hallo liebe Community, Ich habe mit Apache einen Server aufgesetzt. Soweit, so gut. Im Heimnet...