Bash 4 unter OS X und macOS Sierra installieren

Seit langem ist die Bourne 4 auf jedem unixoiden System verfügbar. Auf jedem? Nein! Nur eine Firma in Cupertino hält der Bash 3 die Treue. Eine Anleitung zum sicheren Umstieg auf Bash 4.

Warum Nummer 4?

Standardmäßig setzt OS X und auch das neue macos Sierra auf die Bourne-again shell, kurz Bash, als Standard-Shell. Allerdings in Version 3 aus dem Jahre 2007. Apple aktualisiert zwar regelmäßig sein Betriebssystem, jedoch die Bash bleibt davon ausgenommen. Für mich persönlich unverständlich, denn gerade die Mischung aus einem unixoiden und einem Consumer-Betriebssystem verschafft einen Mac bei Entwicklern die notwendige Attraktivität.

Neben dem Umstand das die ausgelieferte Bash-Version gut neun Jahre alt ist, stellt Version 4 der Bash auch viele neue Features bereit. Das attraktivste Feature davon für mich sind assoziative Arrays, auf die ich nicht mehr verzichten wollte.

Apple liefert mit OS X und macOS Sierra immer noch die Bash 3 aus
> /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15)
Copyright (C) 2007 Free Software Foundation, Inc.

Umstieg auf Bash 4

Die Bash 4 kann zusätzlich neben der Bash 3 über Homebrew oder MacPorts mit ein paar Schritten installiert werden.

Note
Für diese Anleitung zum Umstieg auf die Bash 4 wird eine funktionsfähige Installation von MacPorts vorausgesetzt.
Bash 4 über MacPorts installieren
# Aktuellen Port der Bash über MacPorts installieren
> sudo -i port install bash
# Version überprüfen
> /opt/local/bin/bash --version
GNU bash, Version 4.4.0(1)-release (x86_64-apple-darwin15.6.0)
Copyright (C) 2016 Free Software Foundation, Inc.
Lizenz GPLv3+: GNU GPL Version 3 oder jünger <http://gnu.org/licenses/gpl.html>

Dies ist freie Software.  Sie darf verändert und verteilt werden.
Es wird keine Garantie gewährt, soweit das Gesetz es zulässt.

Damit die nun installierte Shell auch als Login-Shell genutzt werden kann, muß sie zur Liste der erlaubten Login-Shells in /etc/shells hinzugefügt werden.

Bash 4 als mögliche Login-Shell konfigurieren
# Anzeigen der aktuell möglichen Shells
> grep "^/" /etc/shells
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
# Neuinstallierte Bash hinzufügen
> sudo bash -c 'echo /opt/local/bin/bash >> /etc/shells'
# Bash 4 als eigene Login-Shell konfigurieren
> chsh -s /usr/local/bin/bash

Wenn die Shell verloren ist

Kurze Zeit nachdem ich auf die Bash 4 umgestiegen bin, wollte ich alle meine Ports neu installieren und habe dafür zuerst alle installierten Ports entfernt — und damit auch meine eigene Login-Shell. Damit hatte ich mir jede Möglichkeit genommen eine Shell zu öffnen und meine Ports erneut zu installieren.

Passiert so etwas, kann die Shell auch über die Systemeinstellungen geändert werden. Dafür werden diese zuerst geöffnet und dann auf die Gruppe Benutzer & Gruppen geklickt.

Systemeinstellungen
Figure 1. Systemeinstellungen unter OS X

Im Panel Benutzer & Gruppen werden links alle Benutzer aufgeführt. Um einen Benutzer bearbeiten zu können, muß das Schloß unten links mit dem Label Zum Bearbeiten auf das Schloss klicken geöffnet werden.

Systemeinstellungen
Figure 2. Verschlossenes Panel zum Bearbeiten von Benutzern
Systemeinstellungen
Figure 3. Geöffnetes Panel zum Bearbeiten von Benutzern

Die Einstellung für die Login-Shell für einen Benutzer ist in den Erweiterten Einstellungen enthalten, die über einen Klick mit der rechten Maustaste auf den zu ändernden Benutzer aufgerufen werden können.

Systemeinstellungen
Figure 4. Aufruf der erweiterten Einstellungen

In den erweiterten Optionen eines Benutzers gibt es ein Feld Anmelde-Shell, über das die zu verwendende Login-Shell eingestellt werden kann. Beispielsweise die vom Betriebssystem mitgelieferte Bash 3 unter /bin/bash.

Systemeinstellungen
Figure 5. Dropdownbox für die Auswahl der Login-Shell

Fazit

Mich hat erneut überrascht, wie viel Unix in OS X enthalten ist und wie gut dieses auch in die übrigen Tools integriert ist. Nicht das ich nicht wüßte, das Darwin, das eigentliche Betriebssystem von OS X und macOS Sierra, auf BSD beruht und vieles nur von Aqua verdeckt wird. Doch das vergißt man leicht bei der täglichen Arbeit.

Viel Freude mit der jetzt jeweils aktuellsten Bash.

Oliver B. Fischer, 28. November 2016

Eine Buildchain muß jeden Tag laufen

Ein Projekt nur nach einer Änderungen am Projekt selber zu bauen führt zu einer trügerischen Sicherheit, denn jedes Software-Projekt sollte einmal täglich einen vollständigen Build durchlaufen. Dennn ob ein Projekt baut, hängt von mehr als dem Projekt selber ab.

Bei Änderung ein Build

Seine Software-Projekte über eine selbst gehostete Continuous Integration-Lösung wie TeamCity oder Jenkins eine SaaS-Lösung à la Travis zu bauen, gehört heute zum guten Ton, sprich sollte Standard sein. Bei jeder Änderung im Projekt wird so geprüft, ob der Code kompiliert und alle Tests erfolgreich ausgeführt werden können. So stellen wir sicher, daß unsere Software sich in einen einwandfreien Zustand befindet. So weit so gut.

Trügerische Sicherheit

Leider führt dies zu einer trügerischen Sicherheit, denn ob ein Projekt baut oder nicht, hängt nicht nur vom Projekt selber ab, sondern auch von seinen externen Abhängigkeiten und dem System auf dem es gebaut wird. Diese Abhängigkeiten können wir nie vollständig kontrollieren. Zwar bieten die heute sich im Einsatz befindenden Build-Systeme die Möglichkeit Abhängkeiten zu Projekt-externen Librarys in Hinsicht auf Version und Quelle genau festzulegen, jedoch garantiert das nicht, daß diese Abhängikeit in dieser Version für immer an genau dieser Stelle zu finden sein wird.

Beispielsweise wurden vor einiger Zeit alle Dienste von Codehaus, inklusive dessen Maven Repositorys, abgeschaltet. Und GitHub-Accounts bestehen manchmal auch nicht für immer.

Häufiger als das jedoch sind Veränderungen auf dem Host, auf dem der Continuous Integration-Server läuft beziehungsweise auf dem der eigentliche Build erfolgt. Abgelaufene Zertifikate, aktualisierte Versionen von genutzten Tools wie Maven oder eine andere Ruby-Version und schon ist der Build kaputt, ohne das sich am Projekt selber etwas geändert hat.

In einem aktiv entwickelten Projekt fallen solche Probleme sofort auf, da es häufig Commits gibt, die einen neuen Build auslösen. Doch sobald die Aktivität abnimmt oder lange Zeit gar nicht mehr an dem Projekt gearbeitet wird, befinden wir uns in einer trügerischen Sicherheit. Jedes Projekt kann potentiell kaputt sein und wir damit nicht in der Lage Fehler zu beheben oder neue Features schnell einzubauen. Wer ein paar wirklich alte und inaktive Projekte hat, kann dies gerne selber überprüfen.

Jeden Tag ein Build

Aus diesem Grunde sind wir in meinem Team dazu übergegangen unsere Projekte jede Nacht zwischen drei und sechs Uhr morgens vollständig zu bauen. Sofern es Probleme dabei gibt, was ab und zu doch schon vorkommt, finden wir diese schnell und können Fehler beheben oder Anpassungen vornehmen. Für uns im Team ist eine wichtige Voraussetzung, um jeder Zeit lieferfähig zu sein.

Daher sollte jedes Projekt einmal pro Tag vollständig gebaut werden, unabhängig davon, ob es Änderungen daran gab oder nicht. Nur so kann sichergestellt werden, jeder Zeit daran weiter arbeiten zu können.

Für uns war dies nur der erste Schritt. Inzwischen sind wir dazu übergegangen unsere Buildchains zu generieren, doch dies ist ein anderes Thema.

Oliver B. Fischer, 23. März 2016

Norman Doors oder Human Centered Design

Heute bin ich via @TandyQ auf dieses kleine Video gestoßen, das wunderbar erklärt, was eine Norman Door ist und was sie mit Human Centered Design zu tun hat.

Oliver B. Fischer, 27. Februar 2016

heise Developer Podcast zum Thema Softwareanalyse mit Graphendatenbanken

Seit einiger Zeit wirke ich am Software-Analysetool jQAssistant mit und beschäftige mich daher mit dem Einsatz von Graphendatenbanken für die Analyse eines Softwareprojekts. Ende letzten Jahres hatten mein Partner Dirk Mahler und ich die Möglichkeit im Rahmen des SoftwareArchitekTOUR-Podcasts zusammen mit Michael Stal vom SoftwareArchitekTOUR-Podcast über die Möglichkeiten und Vorteile der Software-Analyse mit Graphdatenbanken zu reden.

Der Podcast ist seit der letzten Woche als Episode 51: Softwareanalyse mit Graphendatenbanken online. Er kann direkt auf der Homepage gehört oder über diesen Link als MP3 heruntergeladen werden.

Oliver B. Fischer, 3. Februar 2016

Tags in einem Git-Repository samt Zeitpunkt ausgeben

Gestern fragte ein Kollege, wann wir das letzte Release einer bestimmten Komponente erzeugt haben. Da wir jedes Release auch in dem zugehörigen Git-Repository taggen, habe ich nach einer Möglichkeit gesucht, mir zu den Tags auch den Zeitpunkt ausgeben zu lassen, an dem das Tag gesetzt wurde. Dank stackoverflow war schnell eine gute Lösung gefunden worden, die ich nur noch um eine Option und etwas Formatierung erweitert habe. git log --no-walk --tags --simplify-by-decoration --pretty="format:%<(25)%d%<(20)%cr(%ai)" gibt jetzt den Tagnamen, das relative Datum und das Datum des Taggens selber in einem festen Spaltenlayout aus.

Alle Tags für jQAssistant ausgeben
$ git log --no-walk --tags --simplify-by-decoration --pretty="format:%<(25)%d%<(35)%cr(%ai)"
 (tag: 1.1.2)            vor 10 Tagen                       (2016-01-24 19:44:55 +0100)
 (tag: 1.1.1)            vor 7 Wochen                       (2015-12-15 08:24:44 +0100)
 (tag: 1.1.0)            vor 2 Monaten                      (2015-11-25 19:26:10 +0100)
 (tag: 1.1.0-RC2)        vor 3 Monaten                      (2015-11-06 18:37:00 +0100)
 (tag: 1.1.0-RC1)        vor 4 Monaten                      (2015-10-10 23:32:19 +0200)
 (tag: 1.0.0)            vor 10 Monaten                     (2015-04-17 14:29:57 +0200)
 (tag: 1.0.0-RC1)        vor 11 Monaten                     (2015-02-28 13:35:14 +0100)
 (tag: 1.0.0-M4)         vor 1 Jahr, und 3 Monaten          (2014-10-27 22:43:59 +0100)
 (tag: 1.0.0-M3)         vor 1 Jahr, und 7 Monaten          (2014-06-24 00:34:20 +0200)
 (tag: 1.0.0-M2)         vor 2 Jahren                       (2014-01-24 08:08:25 +0100)
 (tag: 1.0.0-M1)         vor 2 Jahren, und 5 Monaten        (2013-08-28 22:37:42 +0200)

Oliver B. Fischer, 3. Februar 2016


Frühere Artikel sind im Blogarchiv verfügbar.