Kapitel 4. Arbeiten mit entfernten Maschinen
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
Die meisten Datenverarbeitungsaufgaben in der Bioinformatik erfordern mehr Rechenleistung, als wir auf unseren Arbeitsplätzen haben, was bedeutet, dass wir mit großen Servern oder Computerclustern arbeiten müssen. Bei einigen Bioinformatikprojekten wirst du wahrscheinlich hauptsächlich über eine Netzwerkverbindung mit entfernten Rechnern arbeiten. Es überrascht nicht, dass die Arbeit mit Remote-Rechnern für Anfänger ziemlich frustrierend sein kann und auch erfahrene Bioinformatiker/innen in ihrer Produktivität einschränken kann. In diesem Kapitel erfährst du, wie du die Arbeit mit entfernten Rechnern so mühelos wie möglich gestalten kannst, damit du dich voll und ganz auf dein Projekt konzentrieren kannst.
Verbindung zu entfernten Rechnern mit SSH
Es gibt viele Möglichkeiten, sich über ein Netzwerk mit einem anderen Rechner zu verbinden, aber die mit Abstand häufigste ist die Secure Shell(SSH). Wir verwenden SSH, weil es verschlüsselt ist (was das Senden von Passwörtern, das Bearbeiten privater Dateien usw. sicher macht) und weil es auf jedem Unix-System vorhanden ist. Wie dein Server, SSH und dein Benutzerkonto konfiguriert sind, bestimmst du oder dein Systemadministrator; dieses Kapitel befasst sich nicht mit diesen Themen der Systemadministration. Das in diesem Kapitel behandelte Material soll dir helfen, häufige SSH-Fragen zu beantworten, die dir ein Systemadministrator stellen könnte (z. B. "Hast du einen öffentlichen SSH-Schlüssel?"). Außerdem lernst du alle Grundlagen, die du als Bioinformatiker brauchst, um dich per SSH in entfernte Rechner einzuwählen.
Um eine SSH-Verbindung zu einem Host (in diesem Fall biocluster.myuniversity.edu) zu initialisieren, verwenden wir den Befehl ssh
:
$
ssh
biocluster.myuniversity.edu
Password:
Last login: Sun Aug 11 11:57:59 2013 from fisher.myisp.com
wsobchak@biocluster.myuniversity.edu$
Wenn du dich über SSH mit einem Remote-Host verbindest, wirst du zur Eingabeaufforderung für das Passwort deines Remote-Benutzerkontos aufgefordert.
Nachdem du dich mit deinem Passwort angemeldet hast, erhältst du eine Eingabeaufforderung für die Shell auf dem Remote-Host. Damit kannst du Befehle auf dem entfernten Rechner genauso ausführen wie auf dem lokalen Rechner.
SSH funktioniert auch mit IP-Adressen, z. B. kannst du dich mit einem Rechner mit ssh
192.169.237.42
verbinden. Wenn dein Server einen anderen Port als den Standardport (Port 22) verwendet oder dein Benutzername auf dem entfernten Rechner sich von deinem lokalen Benutzernamen unterscheidet, musst du diese Details beim Verbindungsaufbau angeben:
$
ssh -p50453
cdarwin@biocluster.myuniversity.edu
Hier haben wir den Port mit dem Flag -p
und den Benutzernamen mit der Syntax user@domain
angegeben. Wenn du keine Verbindung zu einem Host herstellen kannst, hilft dirssh -v
(-v
für ausführliche Informationen), das Problem zu erkennen. Du kannst die Ausführlichkeit erhöhen, indem du -vv
oder -vvv
verwendest; siehe man ssh
für weitere Informationen.
Speichern deiner häufigen SSH-Hosts
Bioinformatiker/innen müssen ständig per SSH auf Server zugreifen, und das Eintippen von IP-Adressen oder langen Domänennamen kann ziemlich mühsam werden. Außerdem ist es mühsam, sich an zusätzliche Details wie den Port des Servers oder deinen Benutzernamen zu erinnern. Die Entwickler von SSH haben eine clevere Alternative entwickelt: die SSH-Konfigurationsdatei. In SSH-Konfigurationsdateien werden Details zu Hosts gespeichert, mit denen du dich häufig verbindest. Diese Datei ist einfach zu erstellen und die Hosts, die in dieser Datei gespeichert sind, funktionieren nicht nur mit ssh
, sondern auch mit zwei Programmen, die wir in Kapitel 6 kennenlernen werden: scp
und rsync
.
Um eine Datei zu erstellen, musst du nur die Datei unter ~/.ssh/config erstellen und bearbeiten. Jeder Eintrag hat die folgende Form:
Host bio_serv HostName 192.168.237.42 User cdarwin Port 50453
Du musst Port
und User
nicht angeben, es sei denn, sie unterscheiden sich von den Standardwerten des entfernten Hosts. Wenn du diese Datei gespeichert hast, kannst du dich per SSH in 192.168.236.42 einwählen, indem du den Alias ssh bio_serv
verwendest, anstatt ssh -p 50453
cdarwin@192.169.237.42
einzutippen.
Wenn du mit vielen Verbindungen zu entfernten Rechnern in vielen Terminal-Tabs arbeitest, ist es manchmal nützlich, sich zu vergewissern, dass du auf dem Host arbeitest, von dem du glaubst, dass du es bist. Du kannst den Hostnamen immer mit dem Befehl hostname
aufrufen:
$
hostnamebiocluster.myuniversity.edu
Wenn du mehrere Konten auf einem Server unterhältst (z. B. ein Benutzerkonto für die Analyse und ein leistungsfähigeres Administrationskonto für Sysadmin-Aufgaben), kann es nützlich sein, zu überprüfen, welches Konto du verwendest. Der Befehl whoami
gibt deinen Benutzernamen zurück:
$
whoamicdarwin
Dies ist vor allem dann sinnvoll, wenn du dich gelegentlich mit einem Administratorkonto mit mehr Rechten anmeldest - die potenziellen Risiken, die mit einem Konto mit Administratorrechten verbunden sind, sind viel höher, daher solltest du immer weg sein, wenn du mit diesem Konto unterwegs bist (und diese Zeit so weit wie möglich minimieren).
Schnelle Authentifizierung mit SSH-Schlüsseln
SSH erfordert dass du dein Passwort für das Konto auf dem entfernten Rechner eingibst. Die Eingabe eines Passworts bei jeder Anmeldung kann jedoch mühsam sein und ist nicht immer sicher (z. B. könnten Tastatureingaben überwacht werden). Eine sicherere und einfachere Alternative ist die Verwendung eines öffentlichen SSH-Schlüssels. Die Kryptographie mit öffentlichen Schlüsseln ist eine faszinierende Technologie, aber die Details sind nicht Gegenstand dieses Buches. Um sich mit SSH-Schlüsseln ohne Passwörter bei entfernten Rechnern anzumelden, müssen wir zunächst ein öffentliches/privates Schlüsselpaar erzeugen. Dies geschieht mit dem Befehl ssh-keygen
. Es ist sehr wichtig, dass du den Unterschied zwischen deinem öffentlichen und deinem privaten Schlüssel kennst: Du kannst deinen öffentlichen Schlüssel an andere Server weitergeben, aber dein privater Schlüssel muss sicher aufbewahrt und darf niemals weitergegeben werden.
Erzeugen wir ein SSH-Schlüsselpaar mit ssh-keygen
:
$
ssh-keygen -b 2048Generating public/private rsa key pair.
Enter file in which to save the key (/Users/username/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/username/.ssh/id_rsa.
Your public key has been saved in /Users/username/.ssh/id_rsa.pub.
The key fingerprint is:
e1:1e:3d:01:e1:a3:ed:2b:6b:fe:c1:8e:73:7f:1f:f0
The key's randomart image is:
+--[ RSA 2048]----+
|.o... ... |
| . . o |
| . * |
| . o + |
| . S . |
| o . E |
| + . |
|oo+.. . . |
|+=oo... o. |
+-----------------+
Dadurch wird ein privater Schlüssel unter ~/.ssh/id_rsa und ein öffentlicher Schlüssel unter~/.ssh/id_rsa.pub erstellt. ssh-keygen
gibt dir die Möglichkeit, ein leeres Passwort zu verwenden, aber es wird allgemein empfohlen, ein echtes Passwort zu benutzen. Falls du dich wunderst: Der Zufallsgenerator, den ssh-keygen
erstellt, dient dazu, deine Schlüssel zu validieren (unter man ssh
findest du weitere Informationen dazu).
Um die passwortlose Authentifizierung mit SSH-Schlüsseln zu nutzen, musst du dich zunächst per SSH bei deinem Remote-Host anmelden und dein Passwort eingeben. Wechsle in das Verzeichnis ~/.ssh und füge den Inhalt deiner öffentlichen Schlüsseldatei(id_rsa.pub, nicht deinen privaten Schlüssel!) an ~/.ssh/authorized_keys an (beachte, dass ~ je nach Betriebssystem der Gegenstelle zu/home/username oder /Users/username erweitert werden kann). Du kannst diese Datei anhängen, indem du deinen öffentlichen Schlüssel von deinem lokalen System kopierst und ihn in die Datei ~/.ssh/authorized_keys auf dem entfernten System einfügst. Einige Systeme haben einen ssh-copy-id
Befehl, der dies automatisch für dich erledigt.
Achte auch hier darauf, dass du deinen öffentlichen Schlüssel und nicht den privaten Schlüssel verwendest. Wenn dein privater Schlüssel versehentlich weitergegeben wird, gefährdet das die Sicherheit der Rechner, auf denen du die schlüsselbasierte Authentifizierung eingerichtet hast. Der private Schlüssel~/.ssh/id_rsa hat nur Lese- und Schreibrechte für den Ersteller, und diese restriktiven Rechte sollten auch so bleiben.
Nachdem du deinen öffentlichen Schlüssel auf dem Remote-Host hinzugefügt hast, versuche dich ein paar Mal einzuloggen. Du wirst feststellen, dass du immer wieder zur Eingabeaufforderung für das Passwort deines SSH-Schlüssels aufgefordert wirst. Wenn du dich fragst, wie du damit Zeit sparen kannst, gibt es noch einen weiteren Trick, den kennen sollte: ssh-agent
. Das Programm ssh-agent
läuft im Hintergrund auf deinem lokalen Rechner und verwaltet deine SSH-Schlüssel. ssh-agent
So kannst du deine Schlüssel verwenden, ohne jedes Mal das Passwort eingeben zu müssen - genau das, was wir wollen, wenn wir uns häufig mit Servern verbinden. Der SSH-Agent läuft in der Regel bereits auf Unix-basierten Systemen, aber falls nicht, kannst du ihn mit eval
um ihn zu starten. Um ssh-agent
ssh-agent
über unseren Schlüssel zu informieren, verwenden wir undssh-add
:
$
ssh-addEnter passphrase for /Users/username/.ssh/id_rsa:
Identity added: /Users/username/.ssh/id_rsa
Jetzt verwaltet der Hintergrundprozess ssh-agent
unseren Schlüssel für uns und wir müssen nicht jedes Mal unser Passwort eingeben, wenn wir uns mit einem entfernten Rechner verbinden. Ich habe einmal ausgerechnet, dass ich mich etwa 16 Mal am Tag mit verschiedenen Rechnern verbinde und im Durchschnitt etwa zwei Sekunden brauche, um mein Passwort einzugeben (Tippfehler mit eingerechnet). Wenn wir davon ausgehen, dass ich an Wochenenden nicht arbeite, ergibt das etwa 8.320 Sekunden oder 2,3 Stunden pro Jahr nur für SSH-Verbindungen. Nach 10 Jahren ist das fast ein ganzer Tag, den ich damit verbringe, mich nur mit Rechnern zu verbinden. Das Erlernen dieser Tricks dauert vielleicht eine Stunde oder so, aber im Laufe eines Berufslebens spart das wirklich Zeit.
Langlaufende Aufträge mit nohup und tmux aufrechterhalten
In Kapitel 3 haben wir kurz besprochen, wie Prozesse (egal ob sie im Vordergrund oder im Hintergrund laufen) beendet werden, wenn wir unser Terminalfenster schließen. Prozesse werden auch beendet, wenn wir die Verbindung zu unseren Servern trennen oder wenn unsere Netzwerkverbindung vorübergehend unterbrochen wird. Dieses Verhalten ist gewollt - dein Programm empfängt das Aufhängungssignal (technisch alsSIGHUP
bezeichnet), das in fast allen Fällen dazu führt, dass deine Anwendung sofort beendet wird. Da wir bei unserer täglichen Arbeit in der Bioinformatik ständig mit entfernten Rechnern arbeiten, brauchen wir eine Möglichkeit, um zu verhindern, dass langlaufende Anwendungen durch Hänger gestoppt werden. Die Verbindung deines lokalen Terminals zu einem entfernten Rechner offen zu lassen, während ein Programm läuft, ist eine unsichere Lösung - selbst in den zuverlässigsten Netzwerken kann es zu kurzen Ausfällen kommen. Wir werden uns zwei bessere Lösungen ansehen: nohup
und Tmux. Wenn du einen Cluster verwendest, gibt es bessere Möglichkeiten, mit Hängern umzugehen (z. B. indem du Batch-Aufträge an die Software deines Clusters übergibst), aber das hängt von deiner spezifischen Cluster-Konfiguration ab. In diesem Fall solltest du deinen Systemadministrator fragen.
nohup
nohup
ist ein einfacher Befehl, der einen Befehl ausführt und vom Terminal gesendete Aufhängungssignale abfängt. Da der Befehl nohup
diese Signale abfängt und ignoriert, wird das Programm, das du gerade ausführst, nicht unterbrochen. Um einen Befehl mit nohup
auszuführen, fügst du einfach nohup
vor deinem Befehl ein:
$
nohup
program1
>
output.txt
&
[1] 10900
Wir führen den Befehl mit allen Optionen und Argumenten wie gewohnt aus, aber durch das Hinzufügen von
nohup
wird das Programm nicht unterbrochen, wenn dein Terminal geschlossen wird oder die Fernverbindung abbricht. Außerdem ist es eine gute Idee, die Standardausgabe und den Standardfehler umzuleiten, wie wir es in Kapitel 3 getan haben, damit du die Ausgaben später überprüfen kannst.nohup
gibt die Prozess-ID-Nummer (oder PID) zurück, mit der du diesen Prozess bei Bedarf überwachen oder beenden kannst (siehe "Prozesse beenden"). Da wir den Zugriff auf diesen Prozess verlieren, wenn wir ihn übernohup
laufen lassen, können wir ihn nur beenden, indem wir uns auf seine Prozess-ID beziehen.
Arbeiten mit entfernten Maschinen über Tmux
Eine Alternative zu nohup
ist die Verwendung eines Terminalmultiplexers. Mit einem Terminal-Multiplexer kannst du nicht nur das Problem des Aufhängens lösen, sondern auch deine Produktivität bei der Arbeit über eine Fernverbindung erheblich steigern. Wir verwenden einen Terminal-Multiplexer namens Tmux, aber eine beliebte Alternative ist GNU Screen. Tmux und Screen haben ähnliche Funktionen, aber Tmux wird aktiver entwickelt und hat einige zusätzliche nützliche Funktionen.
Tmux (und Terminal-Multiplexer im Allgemeinen) ermöglichen es dir, eine Sitzung mit mehreren Fenstern zu erstellen, von denen jedes seine eigenen Prozesse ausführen kann. Tmux-Sitzungen sind persistent, d.h. alle Fenster und ihre Prozesse können leicht wiederhergestellt werden, indem die Sitzung erneut verbunden wird.
Wenn du Tmux auf einem entfernten Rechner ausführst, kannst du eine dauerhafte Sitzung aufrechterhalten, die nicht verloren geht, wenn deine Verbindung unterbrochen wird oder du dein Terminalfenster schließt, um nach Hause zu gehen (oder sogar dein Terminalprogramm beendest). Vielmehr können alle Tmux-Sitzungen wieder mit dem Terminal verbunden werden, an dem du dich gerade befindest - wähle dich einfach per SSH wieder in den entfernten Rechner ein und verbinde die Tmux-Sitzung erneut. Alle Fenster bleiben ungestört und alle Prozesse laufen weiter.
Installieren und Konfigurieren von Tmux
Tmux ist über die meisten Paket-/Portmanager verfügbar. Unter OS X kann Tmux über Homebrew und unter Ubuntu über apt-get
installiert werden. Nachdem du Tmux installiert hast, empfehle ich dir, das Verzeichnis dieses Kapitels auf GitHub aufzurufen und die Datei .tmux.conf in dein Heimatverzeichnis herunterzuladen. Genauso wie deine Shell Konfigurationen aus ~/.profile oder ~/.bashrc lädt, lädt Tmux seine Konfigurationen aus ~/.tmux.conf. Die minimalen Einstellungen in der Datei.tmux.conf erleichtern dir das Erlernen von Tmux, indem sie dir eine nützliche Anzeigeleiste am unteren Rand bieten und einige der Tastenbelegungen von Tmux in solche ändern, die unter Tmux-Benutzern häufiger vorkommen.
Tmux-Sitzungen erstellen, trennen und anhängen
Mit Tmux kannst du mehrere Sitzungen haben, und innerhalb von kann jede Sitzung mehrere Fenster haben. Jede Tmux-Sitzung ist eine eigene Umgebung. Normalerweise verwende ich für jedes Projekt, an dem ich arbeite, eine eigene Sitzung. Zum Beispiel könnte ich eine Sitzung für das Mais-SNP-Calling haben, eine für die Entwicklung eines neuen Tools und eine weitere für das Schreiben von R-Code zur Analyse von Drosophila-Genexpressionsdaten. In jeder dieser Sitzungen habe ich mehrere Fenster. In meinem Mais-SNP-Calling-Projekt könnte ich zum Beispiel drei Fenster geöffnet haben: eines für die Interaktion mit der Shell, eines mit einem Projektnotizbuch in meinem Texteditor und ein weiteres mit einer Unix-Handbuchseite. Beachte, dass sich alle diese Fenster innerhalb von Tmux befinden; das Konzept deines Terminalprogramms von Tabs und Fenstern ist völlig anders als das von Tmux. Im Gegensatz zu Tmux kann dein Terminal keine dauerhaften Sitzungen verwalten.
Lass uns eine neue Tmux-Sitzung erstellen. Um unsere Beispiele etwas zu vereinfachen, machen wir das auf unserem lokalen Rechner. Um jedoch Sitzungen auf einem entfernten Rechner zu verwalten, müssen wir Tmux auf dem entfernten Rechner starten (das ist für Anfänger oft verwirrend). Um Tmux auf einem entfernten Rechner zu starten, brauchen wir uns nur per SSH in unseren Rechner einzuwählen und Tmux dort zu starten. Nehmen wir an, wir wollen eine Tmux-Sitzung erstellen, die unserem Beispiel für den Aufruf von Maize-SNPs entspricht:
$
tmux new-session -s maize-snps
Tmux verwendet Unterbefehle; der gerade gezeigte new-session
Unterbefehl erstellt neue Sitzungen. Die-s
Option gibt dieser Sitzung einfach einen Namen, damit sie später leichter zu identifizieren ist. Wenn du den Anweisungen folgst und die Datei .tmux.confrichtig in deinem Heimatverzeichnis abgelegt hast, sollte deine Tmux-Sitzung wiein Abbildung 4-1 aussehen.
Tmux sieht genauso aus wie eine normale Eingabeaufforderung, mit Ausnahme der Statusleiste, die am unteren Rand des Bildschirms hinzugefügt wurde (wir werden später mehr darüber sprechen). Wenn Tmux geöffnet ist, interagieren wir mit Tmux über Tastaturkürzel. Diese Tastenkombinationen basieren alle darauf, dass du zuerst die Tasten Strg und a drückst und dann eine bestimmte Taste hinzufügst (indem du zuerst Strg-a loslässt). Standardmäßig verwendet Tmux Strg-b statt Strg-a, aber das ist eine Änderung, die wir in unserer .tmux.conf vorgenommen haben, um der von den meisten Tmux-Nutzern bevorzugten Konfiguration zu folgen.
Die nützlichste Funktion von Tmux (und Terminalmultiplexern im Allgemeinen) ist die Möglichkeit, Sitzungen zu trennen und wieder zu verbinden, ohne dass unsere Arbeit verloren geht. Schauen wir uns an, wie das in Tmux funktioniert. Geben wir zunächst etwas in unsere leere Shell ein, damit wir diese Sitzung später wiedererkennen: echo "hello, tmux"
. Um eine Sitzung zu trennen, verwenden wir Control-a, gefolgt von d (für detach). Nach dieser Eingabe wird Tmux geschlossen und du kehrst zu deiner normalen Eingabeaufforderung für die Shell zurück.
Nachdem wir uns getrennt haben, können wir sehen, dass Tmux unsere Sitzung aufrechterhalten hat, indem wirtmux
mit dem Unterbefehl list-sessions
aufrufen:
$ tmux list-sessions maize-snps: 1 windows (created Mon Feb 10 00:06:00 2014) [180x41]
Jetzt wollen wir unsere Sitzung wieder verbinden. Wir verbinden die Sitzungen mit dem Unterbefehlattach-session
, aber auch der kürzere attach
funktioniert:
$
tmux attach
Da wir nur eine Sitzung laufen haben (unsere maize-snps
Sitzung), müssen wir nicht angeben, welche Sitzung wir anhängen wollen. Hätten wir mehr als eine Sitzung laufen, wären bei der Ausführung vonlist-sessions
alle Sitzungsnamen aufgelistet worden und wir könnten eine bestimmte Sitzung mit -t
<session-name>
wieder anhängen. Wenn nur eine Tmux-Sitzung läuft, ist tmux attach
gleichbedeutend mit tmux attach-session -t maize-snps
.
Die Verwaltung von Remote-Sitzungen mit Tmux unterscheidet sich nicht von der Verwaltung lokaler Sitzungen, wie wir sie zuvor durchgeführt haben. Der einzige Unterschied besteht darin, dass wir unsere Sitzungen auf dem entfernten Host erstellen, nachdem wir uns mit SSH verbunden haben. Wenn wir unsere SSH-Verbindung schließen (entweder absichtlich oder unabsichtlich aufgrund eines Netzwerkabbruchs), trennt Tmux alle aktiven Sitzungen.
Arbeiten mit Tmux Windows
Jede Tmux-Sitzung kann auch mehrere Fenster enthalten. Das ist besonders praktisch, wenn du auf entfernten Rechnern arbeitest. Mit den Fenstern von Tmux kann eine einzige SSH-Verbindung zu einem entfernten Rechner mehrere Aktivitäten in verschiedenen Fenstern unterstützen. Mit Tmux kannst du auch mehrere Fenster innerhalb eines Fensters erstellen, mit denen du deine Fenster in Teile aufteilen kannst. Sieh in der Tmux-Handbuchseite nach (z. B. mit man tmux
) oder lies eines der vielen hervorragenden Tmux-Tutorials im Internet.
Wie andere Tmux-Tastenkombinationen auch, erstellen und wechseln wir Fenster mit Control-aund einer anderen Taste. Um ein Fenster zu erstellen, drückst du Strg-a c, und mit Strg-a n und Strg-a p wechselst du zum nächsten bzw. vorherigen Fenster.In Tabelle 4-1 sind die am häufigsten verwendeten Tmux-Tastenkombinationen aufgeführt. Eine vollständige Liste findest du unter man tmux
oder drücke Strg-a ? in einer Tmux-Sitzung.
Tastenfolge | Aktion |
---|---|
Steuerung-ad |
Lösen |
Steuerung-ac |
Neues Fenster erstellen |
Steuerung-an |
Zum nächsten Fenster gehen |
Steuerung-ap |
Zum vorherigen Fenster gehen |
Steuerung-a& |
Aktuelles Fenster löschen ( |
Steuerung-a, |
Aktuelles Fenster umbenennen |
Steuerung-a? |
Alle Tastenfolgen auflisten |
In Tabelle 4-2 sind die am häufigsten verwendeten Tmux-Unterbefehle aufgeführt.
Unterbefehl | Aktion |
---|---|
|
Liste alle Sitzungen auf. |
|
Erstelle eine neue Sitzung mit dem Namen "Sitzungsname". |
|
Füge eine Sitzung mit dem Namen "Sitzungsname" hinzu. |
|
Füge eine Sitzung mit dem Namen "Sitzungsname" hinzu und löse sie zuerst auf. |
Wenn du Emacs als Texteditor verwendest, wirst du schnell merken, dass die Tastenkombination Strg-a im Weg sein kann. Um ein wortwörtliches Control-a einzugeben (so wie man in Emacs oder der Bash-Shell zum Anfang der Zeile springt), benutze Control-aa.
Get Bioinformatik Datenkenntnisse now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.