Einkaufen ohne Maske

Neulich ist es tatsächlich passiert. Ich betrat den Laden, ohne vorher eine Maske aufzusetzen. Und niemand hat etwas gesagt. Aber wie konnte das passieren?

Ganz einfach. Nach einer ausgedehnten Radtour hatte wohl die Konzentration etwas nachgelassen. Ich wollte einfach nur nach hause und vorher noch eine Kleinigkeit einkaufen. Und es war ein Laden, den ich vorher noch nie besucht hatte. Und das Rad ist auch nicht mein normales Transportmittel beim Einkaufen. Meistens kaufe ich nur einmal in der Woche ein und dann mache ich es mit dem Auto. Inzwischen ist es da schon normal, dass der erste Griff an die Mittelkonsole zum Chip für den Einkaufswagen und der zweite zur Maske geht. Mangelnde Konzentration und eine unbekannte Situation passen also anscheinend nicht zusammen.

Viel interessanter fand ich, was geschah, nachdem mir das Fehlen der Maske bewusst wurde. Als erste Reaktion zuckte meine Hand zum Rucksack. Da steckt in einer Seitentasche immer eine Maske. Danach der Gedanke „Na und. Maske ist doch nicht mehr Pflicht.“ Also weiter oben ohne. Aber ganz wohl fühlte ich mich eigentlich nicht. Nicht dass es mich störte, keine Maske zu tragen, ganz im Gegenteil, und auch nicht, dass ich Angst hatte, mich plötzlich anzustecken. Aber trotzdem ertappte ich mich, wie ich unauffällig die anderen Kunden musterte, ob die vielleicht alle eine Maske trügen. Aber ich war nicht allein. Weder die Kunden noch die Angestellten trugen Maske.

Eins ist mir in den letzten Tagen seit Aufhebung der Maskenpflicht allerdings auch aufgefallen. Je besser der Ruf oder die Lage des Geschäfts ist, um so mehr Kunden tragen dort immer noch eine Maske.

#include<> oder #include““

Ich ärgere mich immer wieder, wenn ich auf GitHub eigentlich interessante Libraries finde und dann feststelle, dass darin die „falschen“ Include-Anweisungen verwendet werden. Aber was ist eigentlich richtig und was ist falsch? Dazu müssen wir erst einmal den Standard bemühen. Da heißt es (frei übersetzt)

#include <...> sucht an den vom System festgelegten Orten nach dem genannten Header.

#include "..." sucht nach der genannten Datei. Wenn diese Suche nicht erfolgreich ist, wird die Suche so fortgesetzt als hätte man den Dateinamen in #include <...> angegeben.

Als erste fällt auf, dass einmal von einem Header und das andere Mal von einer Datei die Rede ist. Ein Grund dafür ist, dass sich der Standard nicht darauf festlegen will, wie die Standard-Header (wie iostream oder cmath) bzw. die darin enthaltenen Definitionen gespeichert werden sollen. In der Praxis sind das meistens Dateien, aber das ist nicht zwingend.

#include <…> heißt also nicht unbedingt „füge an dieser Stelle den Inhalt der genannten Datei ein“, sondern eher „füge hier alle Definitionen ein, die vom Standard in dem genannten Header sein sollten“. Es ist also durchaus möglich, dass der Compiler alle Definitionen aus den Standard-Headern kennt, diese aber erst dann verwendet, wenn der entsprechende Header aktiviert wurde.

Es kann daher nicht falsch sein, wenn man es sich zur Angewohnheit macht, die im Standard definierten Header immer mit #include <…> verwendet. Es ist aber definitiv falsch, wenn man eigene Header-Dateien, also die .h, .hpp oder .hxx Dateien, die im Projekt selbst definiert und verwendet werden, auch mit #include <…> einfügt. Für diese Dateien ist #include „…“ die einzige richtige Lösung.

Aber wie sieht es mit den ganzen anderen Header-Dateien aus, die mit der Entwicklungsumgebung bzw. einem SDK (z.B. die ganzen Windows Header) oder anderen Bibliotheken (z.B. denen von GitHub) aus?

Für die ist #include „…“ jedenfalls nicht falsch. Denn es sind keine Header im Sinne des Standards, sondern Dateien, also ein Fall für #include „…“. Das kann aber bei der großen Zahl von Header-Dateien schnell zu einem Problem werden. Was passiert denn, wenn man zufällig zwei verschiedene Header-Dateien mit gleichen Namen hat. Ich bin einmal, als der cstring Header noch string.h hieß), fast daran verzweifelt, dass der Compiler strlen nicht kannte. Bis sich herausstellte, dass ich #include „string.h“ geschrieben hatte und im Projekt auch eine Datei string.h war, und der Compiler meine Datei statt des Standard-Headers eingefügt hat.

Daraus habe ich meine Schlüsse gezogen und (für mich) Regeln für den Umgang mit #include <…> und #include „…“ aufgestellt. Aber vorher galt es herauszufinden wie mein Compiler (Visual C++) nach Headern und Header-Dateien sucht.

Für #include <…> sucht dieser Compiler

  1. In den mit /I angegebenen Verzeichnissen in der angegebenen Reihenfolge.
  2. In den in der INCLUDE Environment Variablen angegebenen Verzeichnissen in der angegebenen Reihenfolge.

Für #include „…“ wird es etwas komplexer

  1. In dem Verzeichnis, in dem sich die Datei, die das #include Anweisung enthält, befindet.
  2. In den Verzeichnissen der offenen Include-Dateien rückwärts zur Reihenfolge der #include Anweisungen.
  3. In den mit /I angegebenen Verzeichnissen in der angegebenen Reihenfolge.
  4. In den in der INCLUDE Environment Variablen angegebenen Verzeichnissen in der angegebenen Reihenfolge.

Für mich habe ich die folgenden Regeln aufgestellt.

  1. Die Include-Verzeichnisse des Compilers und des Windows SDK werden nicht verändert. Ich überlasse es dem Compiler bzw. dem SDK wie die Dateien gefunden werden (/I Option oder INCLUDE Variable). Für den Zugriff wird immer #include <…> verwendet.
  2. Includes anderer Bibliotheken kommen, wenn möglich, in Unterverzeichnisse eines weiteren Include-Verzeichnisses (C:/ho/dev/inc). Dieses Verzeichnis (nicht die Unterverzeichnisse) kommt ebenfalls in den Suchpfad. Für den Zugriff wird immer #include <library/…> verwendet, wobei library der Name des Unterverzeichnisses von C:/ho/dev/inc ist.
  3. Includes des Projekts selbst oder von Bibliotheken, die Teil des Projekts sind, bleiben, wo sie sind. Auf sie wird mit #include „…“ mit einem relativen Pfad vom Verzeichnis der Datei, die das #include enthält, zugegriffen.
  4. Innerhalb einer Bibliothek in einem Unterverzeichnis von C:/ho/dev/inc wird auf die eigenen, geschachtelten Header mit #include „…“ (evtl. mit einem relativen Pfad) zugegriffen.

Punkt 4 ist bei der Entwicklung eigener Bibliotheken wichtig. Dadurch wird sichergestellt, dass beim erstellen der Bibliothek die aktuellen Header im Source-Verzeichnis verwendet werden und nicht die evtl. veralteten im globalen Include-Verzeichnis.

GIT Server unter Linux installieren

Die vergangenen Tage habe ich mich damit beschäftig, einen GIT Server unter Linux zu installieren. Nach ein paar Fehlschlägen ist es mir schließlich irgendwie gelungen. Um das so gelernte beim nächsten Mal (falls es denn ein solches gibt) nicht erst mühsam im Internet zusammensuchen zu müssen, habe ich mich entschlossen, meinen Weg zu diesem kleinen Erfolg hier aufzuschreiben. Vielleicht hilft es ja nicht nur mir, sondern auch anderen Linux-Neulingen.

Voraussetzungen

Was ich vorgefunden habe, war ein funktionierender Linux-Rechner (Mint 20) mit SSH Zugang und ein Benutzer mit den erforderlichen Rechten für sudo.

Server einrichten

Ich wollte mir möglichst wenig Arbeit machen. Daher wollte ich auf einen Server mit Web-Oberfläche verzichten. Einfach sollte es sein und funktionieren. Daher habe ich mich für GIT über SSH entschieden. Der SSH Zugang war schon vorhanden und GIT war auch schon installiert. Also musste ich nur noch den GIT Server einrichten. Dabei war dieserArtikel von Andrew Hoog sehr hilfreich.

GIT installieren

sudo apt install git

Neuen Benutzer für GIT anlegen

sudo adduser --disabled-password git
sudo su git
cd ~
mkdir repos
mkdir .ssh && chmod 700 .ssh
touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys

Zur Sicherheit sollte das normale Login für den git User unterbunden werden. Dieser Benutzer sollte nur die git-shell verwenden dürfen. Evtl. muss die git-shell vorher noch „installiert“ werden. Sehen wir also nach, ob sie bereits installiert ist.

cat /etc/shells

Wenn git-shell irgendwo in der angezeigten Liste erscheint, ist sie bereits installiert. Wenn sie fehlt, müssen wir sie zur Liste hinzufügen.

which git-shell
sudo nano /etc/shells

Der erste Befehl zeigt den vollständigen Pfad der Shell an. Wir merken uns den Pfad und fügen ihn mit dem zweiten Befehl zu /etc/shells hinzu. Eine Alternative zu diesen beiden Befehlen wäre wohl

sudo which git-shell >> /etc/shells

Ich habe es aber nicht ausprobiert und gebe daher darauf auch keine Garantie.

Zum Schluss muss der git User noch gezwungen werden, git-shell zu verwenden.

sudo chsh git -s $(which git-shell)

Benutzer hinzufügen

Für jeden Benutzer des GIT Servers muss ein öffentlicher Schlüssel hinterlegt werden. Nehmen wir einmal an, diese Schlüssel befinden sich bereits in den Dateien git-user1.pub, git-user2.pub usw. im Verzeichnis /tmp. Mit diesen Befehlen ordnen wir die Schlüssel (und deren Besitzer) dem git Account zu.

sudo cat /tmp/git-user1 >> /home/git/.ssh/authorized_keys
sudo cat /tmp/git-user2 >> /home/git/.ssh/authorized_keys
...

Repositorys einrichten

Mit folgenden Befehlen wird ein neues Repository in /home/git/repos eingerichtet:

ssh ich@my_server
cd /home/git/repos
sudo mkdir test.git
cd test.git && sudo git init --bare && cd ..
sudo chown -R git.git test.git 

Natürlich kann man sich dafür ein kleines Skript schreiben, das den Namen des Repositorys als Parameter bekommt. Wenn man dieses Skript newrepo nennt, kann man ein neues Repository leicht mit zwei Befehlen erzeugen.

ssh ich@my_server
sudo ./newrepo repo_name

Clients einrichten

Auf jedem Rechner, von dem aus wir auf den GIT Server zugreifen wollen, müssen wir noch ein paar kleine Vorbereitungen treffen.

Zuerst müssen wir ein Schlüsselpaar erzeugen und den öffentlichens Schlüssel auf den Server kopieren, so dass wir ihn da zu den erlaubten Schlüsseln hinzufügen können (s. Benutzer hinzufügen)

cd ~/.ssh
# Windows: cd c:\users\ich\.ssh
# Schlüsselpaar erzeugen.
# Wenn nach dem Namen gefragt wird, geben wir „ich-git“ ein.
ssh-keygen
# Öffentlichen Schlüssel auf Server kopieren
scp ich-git.pub ich@my_server:/tmp

Jetzt müssen wir uns nur noch mit dem richtigen Schlüssel anmelden. Dazu fügen wir den folgenden Text in unsere SSH Konfiguration in ~/,ssh/config (unter Windows c:\users\ich\.ssh\config) ein.

Host git
 User git
 Hostname my_server
 IdentityFile ~/.ssh/ich-git

Jetzt können wir das erste Repository vom Server holen. Die URL dafür ist git:repos/test.git, also

git clone git:/repos/test.git

Der Server-Name git wird durch den „Host“ Eintrag in der SSH Konfiguration übersetzt in git@my_server. Zur Anmeldung wird der angegebene Schlüssel, dessen öffentlicher Teil auf dem Server hinterlegt sein muss, verwendet.

Auf meinem Windows-Rechner ist GIT for Windows installiert. Damit werden auch die erforderlichen Tools (ssh.exe, ssh-keygen.exe und scp.exe installiert). Je nach Einstellungen bei der Installation, kann es sein, dass die UnixTools nur in der git-bash im Suchpfad sind. Wenn sie (wie bei mit) im globalen Suchpfad gefunden werden, kann statt git-bash auch cmd, tcc oder eine anderer Shell verwendet werden.

Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start writing!