On this Page


Latest News

↑ top


Terminal · Dateisystem · Prozesse · Netzwerk · Administration

Linux-Grundlagen

Linux lässt sich vollständig über die grafische Oberfläche bedienen – seine eigentliche Stärke zeigt sich jedoch im Terminal. Dort lassen sich Dateien verwalten, Programme starten, Systeme aktualisieren, Prozesse überwachen, Netzwerke untersuchen, Raspberry Pis fernsteuern und wiederkehrende Aufgaben automatisieren.

Die folgenden Beispiele orientieren sich vor allem an Debian, Ubuntu und Raspberry Pi OS. Viele grundlegende Befehle funktionieren jedoch auf praktisch jeder Linux-Distribution.

Das Terminal ist keine Sammlung magischer Befehle. Im Grunde führt man immer ein Programm aus und übergibt ihm Argumente: befehl option argument. Wer dieses Prinzip verstanden hat, hat bereits einen erheblichen Teil der Kommandozeile verstanden.

1. Wie ein Linux-Befehl aufgebaut ist

Grundform

befehl option argument

Beispiel:

ls -lah /home
  • ls – das auszuführende Programm
  • -l – ausführliche Darstellung
  • -a – auch versteckte Dateien anzeigen
  • -h – Dateigrößen menschenlesbar darstellen
  • /home – das Argument bzw. Ziel

Kurze Optionen kombinieren

Statt:

ls -l -a -h

kann man bei vielen Programmen schreiben:

ls -lah

Nicht jede Option funktioniert bei jedem Befehl gleich. -r bedeutet beispielsweise häufig „rekursiv“, ist aber keine universelle Regel.

2. Hilfe bekommen – bevor man Befehle errät

man – das Handbuch

man ls
man cp
man ssh

Öffnet die sogenannte man page eines Programms.

  • / – scrollen
  • /wort – nach einem Begriff suchen
  • n – nächster Treffer
  • q – schließen

--help – Kurzfassung

ls --help
grep --help
python3 --help

Meist schneller als eine vollständige Manual-Seite.

Woher kommt ein Befehl?

command -v python3
command -v git
which python3
type cd
type ls

Besonders type ist nützlich, weil manche „Befehle“ keine eigenständigen Programme, sondern Shell-Builtins oder Aliase sind.

3. Tastaturkürzel, die man ständig braucht

Kürzel Funktion Warum nützlich?
Ctrl+C Laufenden Prozess abbrechen Der wichtigste Notausgang des Terminals.
Ctrl+L Terminal leeren Entspricht weitgehend clear.
Ctrl+D EOF / Sitzung beenden Kann beispielsweise eine SSH-Sitzung oder Shell schließen.
Ctrl+A Zum Zeilenanfang Praktisch bei langen Befehlen.
Ctrl+E Zum Zeilenende Das Gegenstück zu Ctrl+A.
Ctrl+U Text vor Cursor löschen Sehr hilfreich beim schnellen Korrigieren.
Ctrl+K Text nach Cursor löschen Praktisch bei langen Kommandos.
TAB Autovervollständigung Verhindert Tippfehler bei langen Dateinamen.
/ Befehlshistorie Frühere Befehle erneut aufrufen und bearbeiten.

4. Das Linux-Dateisystem verstehen

Anders als unter Windows gibt es nicht für jedes Laufwerk einen eigenen Buchstaben wie C: oder D:. Linux verwendet einen einzigen Verzeichnisbaum, dessen oberster Punkt / heißt.

Pfad Bedeutung
/ Wurzel des gesamten Dateisystems – „root directory“.
/home Home-Verzeichnisse normaler Benutzer.
/home/julian Beispiel für das persönliche Home-Verzeichnis eines Benutzers.
/etc Systemweite Konfigurationsdateien.
/var Veränderliche Daten, etwa Logs, Caches und Serverdaten.
/var/log Viele klassische Systemprotokolle.
/tmp Temporäre Dateien.
/usr Programme, Bibliotheken und gemeinsam genutzte Daten.
/dev Geräte werden unter Linux als Dateien repräsentiert.
/mnt Traditioneller Ort für manuell eingehängte Dateisysteme.
/media Häufig automatisch eingehängte USB-Sticks und Datenträger.
/proc Virtuelles Dateisystem mit Informationen über Prozesse und Kernel.
/sys Virtuelle Schnittstelle zu Geräten und Kernel-Subsystemen.

5. Absolute und relative Pfade

Absoluter Pfad

/home/julian/projekte/logger.py

Beginnt mit / und beschreibt den vollständigen Weg vom Root-Verzeichnis aus.

Relativer Pfad

projekte/logger.py

Wird relativ zum aktuellen Arbeitsverzeichnis interpretiert.

Wichtige Kurzformen

  • . – aktuelles Verzeichnis
  • .. – übergeordnetes Verzeichnis
  • ~ – eigenes Home-Verzeichnis
  • - – bei cd: vorheriges Verzeichnis
cd ..
cd ~
cd ~/projekte
cd -

6. Im Dateisystem navigieren

pwd

pwd

Zeigt den absoluten Pfad des aktuellen Arbeitsverzeichnisses.

ls

ls
ls -l
ls -la
ls -lah
ls /var/log

Zeigt Dateien und Verzeichnisse.

  • -l – Details
  • -a – inklusive versteckter Dateien
  • -h – KB, MB, GB statt Rohbytes

cd

cd ~/projekte
cd ..
cd /
cd ~
cd -

Ändert das aktuelle Arbeitsverzeichnis.

7. Dateien und Verzeichnisse erstellen

mkdir – Verzeichnis erstellen

mkdir logs
mkdir projekt
mkdir -p projekt/data/archive

Mit -p werden fehlende Zwischenverzeichnisse automatisch mit erstellt.

touch – Datei anlegen

touch notes.txt
touch logger.py

Existiert die Datei bereits, wird lediglich ihr Zeitstempel aktualisiert.

8. Dateien kopieren, verschieben und umbenennen

cp – kopieren

cp config.txt config_backup.txt
cp config.txt ~/backup/
cp -r projekt projekt_backup
cp -rv projekt ~/backup/
  • -r – Verzeichnisse rekursiv kopieren
  • -v – anzeigen, was kopiert wird
  • -i – vor Überschreiben nachfragen

mv – verschieben oder umbenennen

mv alt.txt neu.txt
mv messung.csv data/
mv projekt ~/archive/

Linux verwendet denselben Befehl für Verschieben und Umbenennen.

9. Dateien löschen – hier beginnt der gefährliche Teil

rm

rm datei.txt
rm -i datei.txt
rm -r alter_ordner
  • -i – vor dem Löschen nachfragen
  • -r – Verzeichnisse rekursiv löschen
  • -f – ohne Nachfrage erzwingen

rmdir

rmdir leerer_ordner

Löscht nur leere Verzeichnisse und ist deshalb deutlich weniger gefährlich.

Wichtig: Die Shell besitzt normalerweise keinen Papierkorb. rm bedeutet tatsächlich löschen. Besonders sudo rm -rf ... sollte niemals blind aus irgendeiner Anleitung kopiert werden.

10. Dateien ansehen

cat

cat config.txt

Gibt die gesamte Datei auf einmal aus. Ideal für kurze Dateien.

less

less /var/log/syslog

Für lange Dateien meist wesentlich angenehmer als cat.

  • /wort – suchen
  • n – nächster Treffer
  • q – beenden

head

head datei.txt
head -n 20 datei.txt

Zeigt den Anfang einer Datei.

tail

tail datei.txt
tail -n 50 log.txt
tail -f log.txt

tail -f beobachtet eine Datei live und ist deshalb hervorragend für Logs geeignet.

11. Dateien direkt im Terminal bearbeiten

nano

nano config.txt
nano logger.py
sudo nano /etc/hosts
  • Ctrl+O – speichern
  • Enter – Dateinamen bestätigen
  • Ctrl+X – schließen
  • Ctrl+W – suchen
  • Ctrl+K – Zeile ausschneiden
  • Ctrl+U – wieder einfügen

12. Dateien und Verzeichnisse suchen

find

find . -name "logger.py"
find . -name "*.py"
find ~/projekte -type f -name "*.json"
find . -type d -name "backup"
find . -type f -size +100M
  • . – Suche hier beginnen
  • -type f – nur Dateien
  • -type d – nur Verzeichnisse
  • -name – Name suchen
  • -iname – Groß-/Kleinschreibung ignorieren

Datei nach Änderungszeit suchen

find . -type f -mtime -1
find . -type f -mtime -7

Findet Dateien, die innerhalb des letzten Tages bzw. der letzten sieben Tage geändert wurden.

13. Text durchsuchen mit grep

Einfache Suche

grep "error" log.txt
grep -i "error" log.txt
grep -n "error" log.txt
  • -i – Groß-/Kleinschreibung ignorieren
  • -n – Zeilennummer anzeigen

Rekursiv durchsuchen

grep -r "BME280" .
grep -rin "error" ~/projekte

Ideal, wenn man nicht mehr weiß, in welcher Datei ein bestimmter Begriff vorkommt.

14. Wildcards – mehrere Dateien gleichzeitig ansprechen

Muster Bedeutung Beispiel
* Beliebig viele Zeichen ls *.jpg
? Genau ein Zeichen ls bild?.jpg
[123] Eines der angegebenen Zeichen ls bild[123].jpg
cp *.jpg bilder/
rm *.tmp
ls sensor_2026-*.csv

Vor einem destruktiven Befehl mit Wildcards ist ein Test mit ls klug: erst ls *.tmp, dann gegebenenfalls rm *.tmp.

15. Leerzeichen und Sonderzeichen in Dateinamen

Ein Leerzeichen trennt normalerweise Argumente:

cd Mein Projekt

würde daher als zwei Argumente interpretiert. Richtig:

cd "Mein Projekt"
cd 'Mein Projekt'
cd Mein\ Projekt

In Skripten ist sauberes Quoting besonders wichtig. Variablen sollten häufig in doppelte Anführungszeichen gesetzt werden:

cp "$datei" "$ziel"

16. Ein- und Ausgabe umleiten

Linux-Programme besitzen standardmäßig drei Datenströme: stdin für Eingaben, stdout für normale Ausgaben und stderr für Fehlermeldungen.

Operator Bedeutung Beispiel
> Ausgabe in Datei schreiben und vorhandenen Inhalt ersetzen ls > files.txt
>> Ausgabe an Datei anhängen date >> log.txt
< Datei als Eingabe verwenden sort < namen.txt
2> Fehlermeldungen umleiten befehl 2> errors.txt
2>&1 Fehlerausgabe mit Standardausgabe zusammenführen befehl > log.txt 2>&1

Beispiele:

echo "Messung gestartet" > log.txt
date >> log.txt
python3 logger.py >> logger.log 2>&1

17. Pipes – die eigentliche Superkraft der Shell

Der Operator | reicht die Ausgabe eines Programms direkt als Eingabe an das nächste Programm weiter.

ps aux | grep python
ls -lah | less
history | grep ssh
cat log.txt | grep "error"

Das letzte Beispiel kann kürzer geschrieben werden:

grep "error" log.txt

Unix folgt stark dem Prinzip: kleine Programme erledigen eine Sache gut und werden miteinander kombiniert. Eine Shell-Pipeline ist deshalb gewissermaßen Lego für Datenströme.

18. Nützliche Werkzeuge zur Textverarbeitung

wc

wc datei.txt
wc -l datei.txt
wc -w datei.txt

Zählt unter anderem Zeilen und Wörter.

sort

sort namen.txt
sort -n zahlen.txt
sort -r namen.txt

uniq

sort namen.txt | uniq
sort namen.txt | uniq -c

uniq erkennt nur unmittelbar aufeinanderfolgende Duplikate; deshalb wird häufig vorher sortiert.

cut

cut -d "," -f 1 daten.csv

Gibt hier die erste Spalte einer kommaseparierten Datei aus.

19. Ausgabe gleichzeitig anzeigen und speichern – tee

python3 logger.py | tee logger.log
python3 logger.py | tee -a logger.log

-a hängt an eine bestehende Datei an.

tee ist außerdem nützlich, wenn eine Datei Root-Rechte benötigt:

echo "wert" | sudo tee /etc/beispiel.conf

Denn bei:

sudo echo "wert" > /etc/beispiel.conf

läuft zwar echo mit sudo, die Umleitung > wird aber weiterhin von der normalen Shell ausgeführt.

20. Befehle logisch miteinander verknüpfen

Operator Bedeutung
; Nächsten Befehl unabhängig vom Erfolg ausführen.
&& Nächsten Befehl nur ausführen, wenn der vorherige erfolgreich war.
|| Nächsten Befehl nur ausführen, wenn der vorherige fehlgeschlagen ist.
& Prozess im Hintergrund starten.
sudo apt update && sudo apt upgrade

mkdir backup && cp config.txt backup/

python3 logger.py || echo "Logger fehlgeschlagen"

python3 logger.py &

21. Hat ein Befehl funktioniert?

echo $?

Zeigt den Exit-Code des zuletzt ausgeführten Programms.

  • 0 – erfolgreich
  • ungleich 0 – Fehler oder besonderer Status
grep "BME280" config.txt
echo $?

22. Befehlshistorie

history
history | grep ssh
history | grep apt

Der letzte Befehl kann mit:

!!

erneut ausgeführt werden.

Ein klassischer Anwendungsfall:

apt update
sudo !!

Dadurch wird der vorherige Befehl als sudo apt update wiederholt.

23. Administratorrechte mit sudo

sudo apt update
sudo nano /etc/hosts
sudo systemctl restart ssh

sudo führt einen einzelnen Befehl mit erhöhten Rechten aus.

Prüfen, welche sudo-Rechte man besitzt:

sudo -l

sudo ist kein Ritual, das man vor jeden Befehl schreiben sollte. Wenn ein normaler Benutzer etwas erledigen kann, sollte es auch als normaler Benutzer erledigt werden.

24. Dateirechte verstehen

ls -l

Eine typische Ausgabe:

-rwxr-xr-- 1 julian julian 1240 Aug 18 12:00 script.sh

Die Rechte sind in drei Gruppen geteilt:

  • Eigentümer
  • Gruppe
  • alle anderen Benutzer

Die Zeichen bedeuten:

  • r – read / lesen
  • w – write / schreiben
  • x – execute / ausführen
  • - – Recht nicht vorhanden

25. Rechte ändern mit chmod

Symbolische Schreibweise

chmod u+x script.sh
chmod g-w datei.txt
chmod o-r geheim.txt
  • u – user
  • g – group
  • o – others
  • a – all

Numerische Schreibweise

  • 4 – lesen
  • 2 – schreiben
  • 1 – ausführen
chmod 644 datei.txt
chmod 755 script.sh
chmod 600 geheim.txt

Typische Rechte:

Modus Bedeutung
644 Eigentümer darf lesen/schreiben; alle anderen nur lesen.
755 Eigentümer darf alles; alle anderen lesen und ausführen.
600 Nur Eigentümer darf lesen und schreiben – typisch für sensible Dateien.

26. Besitzer und Gruppen ändern

chown julian datei.txt
chown julian:julian datei.txt
sudo chown -R julian:julian projekt/

chown bedeutet change owner. -R wirkt rekursiv auf alle Inhalte eines Verzeichnisses.

27. Benutzer und Gruppen

whoami
id
groups
who
w
  • whoami – aktueller Benutzer
  • id – Benutzer-ID und Gruppen
  • groups – Gruppenmitgliedschaften
  • who – angemeldete Benutzer
  • w – angemeldete Benutzer und deren Aktivitäten

Auf Debian-basierten Systemen einen Benutzer anlegen:

sudo adduser neuerbenutzer

Benutzer zu einer Gruppe hinzufügen:

sudo usermod -aG dialout julian

Nach einer Änderung der Gruppenmitgliedschaft ist meist eine neue Anmeldung erforderlich, damit die neue Gruppe für die Sitzung wirksam wird.

28. Laufende Prozesse untersuchen

ps

ps
ps aux
ps aux | grep python

pgrep

pgrep python
pgrep -a python

Findet Prozesse direkt anhand ihres Namens.

top

top

Live-Ansicht von CPU, Arbeitsspeicher und Prozessen. Mit q beenden.

htop

sudo apt install htop
htop

Komfortablere interaktive Alternative zu top.

29. Prozesse beenden

kill 1234
kill -TERM 1234
kill -KILL 1234
pkill python3
pkill -f logger.py

Normalerweise sollte zuerst ein reguläres Beenden versucht werden. SIGKILL bzw. kill -9 ist die Brechstange.

kill -9 gibt einem Programm keine Gelegenheit mehr, Dateien sauber zu schließen, Daten zu speichern oder aufzuräumen. Nur verwenden, wenn ein normaler Abbruch tatsächlich nicht funktioniert.

30. Vordergrund- und Hintergrundprozesse

python3 logger.py &
jobs
fg
bg

Ein laufender Vordergrundprozess kann außerdem mit Ctrl+Z angehalten werden.

Ctrl+Z
bg
jobs
fg

Dabei gilt:

  • Ctrl+Z – Prozess pausieren
  • bg – pausierten Prozess im Hintergrund fortsetzen
  • fg – Hintergrundprozess wieder in den Vordergrund holen

31. Prozess nach SSH-Abmeldung weiterlaufen lassen

nohup python3 logger.py > logger.log 2>&1 &

Dadurch läuft das Programm weiter, wenn die Terminal- oder SSH-Sitzung beendet wird.

Für dauerhaft laufende Dienste ist allerdings systemd meist die wesentlich sauberere Lösung.

32. Dienste mit systemctl verwalten

Moderne Debian-/Ubuntu-/Raspberry-Pi-Systeme verwenden üblicherweise systemd für Hintergrunddienste.

systemctl status ssh
sudo systemctl start ssh
sudo systemctl stop ssh
sudo systemctl restart ssh
sudo systemctl enable ssh
sudo systemctl disable ssh
  • status – Zustand anzeigen
  • start – Dienst starten
  • stop – Dienst stoppen
  • restart – neu starten
  • enable – beim Booten automatisch starten
  • disable – Autostart deaktivieren

Prüfen, ob ein Dienst beim Booten aktiviert ist:

systemctl is-enabled ssh

Prüfen, ob er gerade läuft:

systemctl is-active ssh

33. Systemlogs mit journalctl

journalctl
journalctl -b
journalctl -p err
journalctl -u ssh
journalctl -u ssh -f
journalctl --since "1 hour ago"
  • -b – Meldungen seit aktuellem Boot
  • -p err – nur Fehler
  • -u – bestimmter systemd-Dienst
  • -f – neue Meldungen live verfolgen

Für einen eigenen Sensor-Dienst beispielsweise:

journalctl -u bme280-logger.service -f

34. Informationen über das System

Kernel

uname -a
uname -r

Distribution

cat /etc/os-release

Hostname

hostname
hostnamectl

Laufzeit

uptime

Arbeitsspeicher

free -h

CPU

lscpu

35. Speicherplatz untersuchen

df – Dateisysteme

df -h

Zeigt belegten und freien Speicher auf eingehängten Dateisystemen.

du – Verzeichnisgrößen

du -sh .
du -sh *
du -sh ~/projekte/*

Ideal, wenn man wissen möchte, welches Verzeichnis den Speicher frisst.

Größte Einträge finden

du -ah . | sort -h | tail -20

Gibt die größten Dateien bzw. Verzeichnisse am Ende der sortierten Liste aus.

36. Festplatten, SD-Karten und USB-Sticks

lsblk
lsblk -f
blkid

lsblk zeigt Blockgeräte und Partitionen. Mit -f werden zusätzlich Dateisystem, UUID und Mountpoint angezeigt.

Beispiel:

NAME        FSTYPE MOUNTPOINT
sda
└─sda1      ext4   /mnt/data
mmcblk0
├─mmcblk0p1 vfat   /boot
└─mmcblk0p2 ext4   /

37. Datenträger ein- und aushängen

sudo mkdir -p /mnt/usb
sudo mount /dev/sda1 /mnt/usb

Danach steht der Inhalt unter:

/mnt/usb

Vor dem Abziehen:

sudo umount /mnt/usb

Nicht einfach einen Datenträger abziehen, während noch geschrieben wird. Ein sauberer umount verhindert Dateisystemschäden.

38. Software installieren und aktualisieren – apt

Paketlisten aktualisieren

sudo apt update

Lädt aktuelle Informationen über verfügbare Pakete. Es werden dabei noch keine Programme aktualisiert.

Installierte Pakete aktualisieren

sudo apt upgrade

Komplettes Upgrade

sudo apt full-upgrade

Darf bei Bedarf Abhängigkeiten verändern und Pakete entfernen oder ersetzen.

Programm installieren

sudo apt install git
sudo apt install i2c-tools
sudo apt install htop

Programm entfernen

sudo apt remove htop
sudo apt purge htop

purge entfernt zusätzlich systemweite Konfigurationsdateien des Pakets.

Nicht mehr benötigte Pakete entfernen

sudo apt autoremove

Pakete suchen:

apt search i2c
apt search python3

Informationen anzeigen:

apt show i2c-tools

Ein typischer Wartungsablauf:

sudo apt update
sudo apt upgrade
sudo apt autoremove

39. Netzwerk – die wichtigsten Befehle

IP-Adressen

ip a

Zeigt Netzwerkinterfaces und zugewiesene IP-Adressen.

Nur lokale IP-Adressen

hostname -I

Besonders auf einem Raspberry Pi praktisch.

Routing

ip route

Zeigt unter anderem das Standard-Gateway.

Erreichbarkeit prüfen

ping raspberrypi.local
ping 192.168.1.20
ping -c 4 1.1.1.1

-c 4 beendet den Test nach vier Paketen automatisch.

40. Offene Ports und Netzwerkverbindungen

ss -tulpn

Typische Optionen:

  • -t – TCP
  • -u – UDP
  • -l – nur lauschende Ports
  • -p – zugehörige Prozesse
  • -n – numerische Adressen statt Namensauflösung

Prüfen, ob beispielsweise ein Webserver auf Port 8000 läuft:

ss -tulpn | grep 8000

41. Namensauflösung prüfen

getent hosts raspberrypi.local
getent hosts example.com

Falls dnsutils installiert ist:

dig example.com
nslookup example.com

42. Einen anderen Linux-Rechner per SSH steuern

SSH ist eines der wichtigsten Werkzeuge für Raspberry Pi und Linux-Server. Es öffnet eine verschlüsselte Terminal-Sitzung auf einem anderen Rechner.

ssh benutzer@hostname

Beispiele:

ssh julian@raspberrypi.local
ssh pi@192.168.1.50

Anderer SSH-Port:

ssh -p 2222 julian@server.local

Bestimmten privaten Schlüssel verwenden:

ssh -i ~/.ssh/id_ed25519 julian@server.local

SSH-Sitzung beenden:

exit

oder:

Ctrl+D

43. SSH-Schlüssel statt Passwort verwenden

Neuen Schlüssel erzeugen:

ssh-keygen -t ed25519

Standardmäßig entstehen beispielsweise:

~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub

Der private Schlüssel darf nicht weitergegeben werden. Die Datei mit .pub ist der öffentliche Schlüssel.

Öffentlichen Schlüssel auf Raspberry Pi übertragen:

ssh-copy-id julian@raspberrypi.local

Danach genügt normalerweise:

ssh julian@raspberrypi.local

44. Häufig verwendete SSH-Verbindungen abkürzen

Datei:

~/.ssh/config

Beispiel:

Host wetterpi
    HostName 192.168.1.50
    User julian
    IdentityFile ~/.ssh/id_ed25519

Danach reicht:

ssh wetterpi

45. Dateien über SSH kopieren – scp

Lokale Datei auf Raspberry Pi kopieren:

scp logger.py julian@raspberrypi.local:~/

Datei vom Raspberry Pi herunterladen:

scp julian@raspberrypi.local:~/logger.csv .

Ganzes Verzeichnis kopieren:

scp -r projekt/ julian@raspberrypi.local:~/

46. Verzeichnisse effizient synchronisieren – rsync

rsync -av projekt/ julian@raspberrypi.local:~/projekt/
  • -a – Archivmodus, erhält viele Dateieigenschaften
  • -v – ausführliche Ausgabe

Bei wiederholten Übertragungen ist rsync häufig besser als scp, weil nur Änderungen übertragen werden.

Bei rsync ist der abschließende Slash bedeutsam: projekt/ meint den Inhalt des Verzeichnisses; projekt kann das Verzeichnis selbst als zusätzliche Ebene kopieren.

47. Dateien aus dem Internet laden

wget

wget https://example.com/datei.zip

curl

curl https://example.com
curl -O https://example.com/datei.zip

Nicht jedes minimale Linux-System installiert beide Werkzeuge standardmäßig.

48. Dateien archivieren und komprimieren

Verzeichnis als .tar.gz archivieren:

tar -czf backup.tar.gz projekt/

Archiv entpacken:

tar -xzf backup.tar.gz

Inhalt ansehen:

tar -tzf backup.tar.gz

Die klassischen Buchstaben:

  • c – create
  • x – extract
  • t – list
  • z – gzip
  • f – folgende Angabe ist der Dateiname

49. Symbolische Links

Ein symbolischer Link ähnelt einer Verknüpfung unter Windows.

ln -s /home/julian/projekte/logger ~/logger

Link anzeigen:

ls -l ~/logger

Ziel eines Links auflösen:

readlink -f ~/logger

50. Herausfinden, was eine Datei tatsächlich ist

file bild.jpg
file programm
file archiv.dat

Linux verlässt sich wesentlich weniger auf Dateiendungen als Windows. Eine Datei namens bild.jpg muss deshalb keineswegs tatsächlich ein JPEG sein.

Weitere Metadaten:

stat datei.txt

51. Python unter Linux

Python-Version prüfen:

python3 --version

Skript starten:

python3 logger.py

Interaktiven Interpreter starten:

python3

Beenden:

exit()

52. Python-Projekte mit virtuellen Umgebungen sauber halten

Python-Pakete sollten für Projekte möglichst nicht wahllos systemweit installiert werden. Eine virtuelle Umgebung isoliert die Abhängigkeiten eines Projekts.

Falls nötig:

sudo apt install python3-venv

Projektordner:

mkdir bme280_logger
cd bme280_logger

Virtuelle Umgebung erstellen:

python3 -m venv .venv

Aktivieren:

source .venv/bin/activate

Danach erkennt man häufig am Prompt:

(.venv) julian@raspberrypi:~/bme280_logger $

Pakete installieren:

python -m pip install requests
python -m pip install smbus2

Installierte Pakete anzeigen:

python -m pip list

Umgebung verlassen:

deactivate

Innerhalb einer aktivierten virtuellen Umgebung ist python in Ordnung. Außerhalb ist auf Debian-/Raspberry-Pi-Systemen python3 die eindeutigere Wahl.

53. Python-Abhängigkeiten dokumentieren

python -m pip freeze > requirements.txt

Später auf einem anderen System:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

Damit lässt sich ein Projekt wesentlich reproduzierbarer auf einen anderen Raspberry Pi oder Rechner übertragen.

54. Mehrere Befehle in ein Shell-Skript packen

Datei erstellen:

nano backup.sh

Beispielinhalt:

#!/usr/bin/env bash

echo "Backup startet..."
date

mkdir -p "$HOME/backups"
cp "$HOME/projekte/config.json" "$HOME/backups/config.json"

echo "Backup abgeschlossen."

Ausführbar machen:

chmod +x backup.sh

Starten:

./backup.sh

Das führende ./ bedeutet: „Führe die Datei aus dem aktuellen Verzeichnis aus.“

55. Shell-Variablen und Umgebungsvariablen

name="Julian"
echo "$name"

Umgebungsvariable setzen:

export SENSOR="BME280"
echo "$SENSOR"

Alle Umgebungsvariablen anzeigen:

env

Wichtige Beispiele:

echo "$HOME"
echo "$USER"
echo "$PATH"
echo "$SHELL"

56. Was ist PATH?

Wenn man:

python3

eingibt, durchsucht die Shell nicht den gesamten Computer. Sie sucht nur in den Verzeichnissen aus der Umgebungsvariable PATH.

echo "$PATH"

Beispielsweise:

/usr/local/bin:/usr/bin:/bin

Deshalb muss ein Programm im aktuellen Verzeichnis häufig explizit so gestartet werden:

./mein_programm

57. Eigene Kurzbefehle mit Aliasen

alias ll='ls -lah'
alias update='sudo apt update && sudo apt upgrade'

Dauerhafte Aliase können beispielsweise in:

~/.bashrc

eingetragen werden.

Danach neu laden:

source ~/.bashrc

58. Raspberry-Pi-spezifische Befehle

Konfiguration

sudo raspi-config

Je nach Raspberry Pi OS lassen sich hier unter anderem SSH, I²C, SPI, Hostname und weitere Schnittstellen konfigurieren.

CPU-Temperatur

vcgencmd measure_temp

Modell anzeigen

cat /proc/device-tree/model

GPIO-Werkzeuge entdecken

pinctrl help

Auf neueren Raspberry-Pi-Systemen steht pinctrl für verschiedene GPIO-Abfragen zur Verfügung.

59. I²C-Geräte suchen

Werkzeuge installieren:

sudo apt install i2c-tools

I²C-Busse anzeigen:

i2cdetect -l

Typischen Raspberry-Pi-I²C-Bus scannen:

i2cdetect -y 1

Eine typische Ausgabe könnte enthalten:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 76 --
70: -- -- -- -- -- -- -- --

In diesem Beispiel wären Geräte an 0x3C und 0x76 vorhanden – typische Adressen etwa für ein SSD1306-OLED und einen BME280.

60. USB- und serielle Geräte finden

lsusb

Serielle Geräte suchen:

ls /dev/ttyUSB*
ls /dev/ttyACM*

Kernelmeldungen nach dem Anstecken ansehen:

dmesg | tail -30

Oder live:

sudo dmesg -w

Das ist besonders nützlich bei Arduino, ESP32, Meshtastic-Geräten oder USB-Seriell-Adaptern.

61. Raspberry Pi oder Linux-Rechner sauber herunterfahren

sudo reboot
sudo shutdown -h now

Alternative:

sudo poweroff

Besonders beim Raspberry Pi sollte die Stromversorgung nicht einfach während laufender Schreibzugriffe getrennt werden. Die SD-Karte ist ein Dateisystem – kein Lichtschalter.

62. Datum, Uhrzeit und Zeitzone

date
timedatectl

Verfügbare Zeitzonen suchen:

timedatectl list-timezones | grep Vienna

Zeitzone setzen:

sudo timedatectl set-timezone Europe/Vienna

63. Befehle automatisch nach Zeitplan starten – cron

Eigene Cronjobs bearbeiten:

crontab -e

Format:

Minute Stunde Tag Monat Wochentag Befehl

Beispiel – jeden Tag um 03:00 Uhr:

0 3 * * * /home/julian/backup.sh

Alle fünf Minuten:

*/5 * * * * /home/julian/script.sh

Eigene Cronjobs anzeigen:

crontab -l

Für dauerhaft laufende Programme ist systemd meist geeigneter. cron eignet sich besonders für Aufgaben, die zu bestimmten Zeitpunkten gestartet werden sollen.

64. Kleine Helfer für Tests und Automatisierung

date

date
date "+%Y-%m-%d %H:%M:%S"

sleep

sleep 5
sleep 10m
sleep 1h

Wartet fünf Sekunden, zehn Minuten bzw. eine Stunde.

watch

watch free -h
watch -n 2 vcgencmd measure_temp

Führt einen Befehl regelmäßig neu aus.

65. Schnell einen lokalen Webserver starten

Für statische HTML-/CSS-/JavaScript-Projekte ist Python hervorragend als einfacher Entwicklungsserver geeignet.

cd ~/web
python3 -m http.server 8000

Danach lokal öffnen:

http://localhost:8000/

Von einem anderen Rechner im lokalen Netzwerk:

http://IP-DES-RECHNERS:8000/

IP-Adresse herausfinden:

hostname -I

Server wieder beenden:

Ctrl+C

66. Typische Debugging-Workflows

„Mein Python-Skript läuft nicht.“

pwd
ls -lah
python3 --version
python3 logger.py

Bei Paketproblemen:

source .venv/bin/activate
python -m pip list

„Mein Raspberry Pi ist im Netzwerk nicht erreichbar.“

hostname
hostname -I
ip a
ip route
ping -c 4 1.1.1.1

SSH prüfen:

systemctl status ssh
ss -tulpn | grep :22

„Mein Sensor wird nicht erkannt.“

i2cdetect -l
i2cdetect -y 1

Wenn nichts erscheint: Verkabelung, Versorgung, SDA/SCL und aktiviertes I²C prüfen.

„Mein Dienst startet nicht.“

systemctl status mein-dienst
journalctl -u mein-dienst -n 50
journalctl -u mein-dienst -f

„Die Festplatte ist voll.“

df -h
du -sh /*
du -sh ~/.* ~/* 2>/dev/null

„Ein Prozess hängt.“

pgrep -a python
ps aux | grep logger
kill PID

Erst wenn das nicht hilft:

kill -9 PID

67. Praktische Befehlsfolgen für den Alltag

System aktualisieren

sudo apt update && sudo apt upgrade

Neues Python-Projekt anlegen

mkdir mein_projekt
cd mein_projekt
python3 -m venv .venv
source .venv/bin/activate
touch main.py
nano main.py

Projekt auf einen Raspberry Pi übertragen

rsync -av mein_projekt/ raspberrypi:~/mein_projekt/

Auf den Raspberry Pi verbinden und Projekt starten

ssh raspberrypi
cd ~/mein_projekt
source .venv/bin/activate
python main.py

Log live verfolgen

tail -f logger.log

Nach Fehlern im Log suchen

grep -in "error" logger.log

68. Kompakte Befehlsreferenz

Befehl Zweck Beispiel
pwd Aktuelles Verzeichnis anzeigen pwd
ls Dateien anzeigen ls -lah
cd Verzeichnis wechseln cd ~/projekte
mkdir Verzeichnis erstellen mkdir -p data/logs
touch Datei anlegen touch notes.txt
cp Kopieren cp -r projekt backup
mv Verschieben / Umbenennen mv alt.txt neu.txt
rm Löschen rm -i datei.txt
cat Datei ausgeben cat config.txt
less Lange Datei lesen less log.txt
head Dateianfang head -n 20 log.txt
tail Dateiende / Logs tail -f log.txt
grep Text suchen grep -rin "error" .
find Dateien suchen find . -name "*.py"
nano Datei bearbeiten nano config.txt
chmod Dateirechte ändern chmod +x script.sh
chown Besitzer ändern sudo chown user:user datei
df Freien Speicher anzeigen df -h
du Verzeichnisgröße du -sh *
ps Prozesse anzeigen ps aux
top Systemlast live top
kill Prozess beenden kill 1234
systemctl Dienste verwalten systemctl status ssh
journalctl Systemlogs anzeigen journalctl -u ssh -f
ip Netzwerk untersuchen ip a
ping Erreichbarkeit prüfen ping -c 4 server.local
ss Ports / Verbindungen anzeigen ss -tulpn
ssh Remote-Terminal ssh user@server
scp Dateien über SSH kopieren scp file user@server:~/
rsync Dateien synchronisieren rsync -av projekt/ server:~/projekt/
apt Software verwalten sudo apt install htop
tar Archive erstellen / entpacken tar -czf backup.tar.gz projekt/
python3 Python starten python3 logger.py
history Alte Befehle anzeigen history | grep ssh
man Handbuch anzeigen man grep

69. Häufige Optionen – aber nicht blind verallgemeinern

Option Häufige Bedeutung Beispiel
-a all / alles ls -a
-l long / ausführliche Darstellung ls -l
-h häufig human-readable df -h
-r häufig recursive cp -r ordner backup
-R häufig ebenfalls recursive chown -R user:user ordner
-f häufig force rm -f datei
-i häufig interactive rm -i datei
-v häufig verbose cp -v a b
-n je nach Programm number, numeric oder Anzahl tail -n 20 log.txt
-y bei apt: Rückfragen automatisch bestätigen sudo apt install -y htop

Optionen sind Eigenschaften des jeweiligen Programms, nicht der Linux-Shell. Deshalb bedeutet beispielsweise -h nicht zwangsläufig immer dasselbe. Im Zweifel: befehl --help oder man befehl.

70. Befehle, bei denen man zweimal hinschauen sollte

rm -rf

Löscht rekursiv und ohne Rückfrage.

rm -rf VERZEICHNIS

Vorher besser:

pwd
ls -lah VERZEICHNIS

sudo

Hebt viele Schutzmechanismen auf. Nicht automatisch verwenden, nur weil ein Befehl sonst scheitert.

chmod -R / chown -R

Rekursive Rechteänderungen können bei einem falschen Pfad sehr viel mehr verändern als beabsichtigt.

Unbekannte Shell-Kommandos aus dem Internet

Befehle nicht blind kopieren – insbesondere nicht, wenn sie mit sudo ausgeführt werden.

71. Ein brauchbares Denkmodell für Linux

  1. Wo bin ich?
    pwd
  2. Was ist hier?
    ls -lah
  3. Was ist diese Datei?
    file datei und stat datei
  4. Was enthält sie?
    less datei
  5. Wo befindet sich etwas?
    find und grep
  6. Was läuft gerade?
    ps, top, systemctl
  7. Warum funktioniert etwas nicht?
    journalctl, Logs, Exit-Code $?
  8. Ist das Netzwerk das Problem?
    ip a, ip route, ping, ss

72. Goldene Regeln für den Linux-Alltag

  • Vor destruktiven Befehlen zuerst pwd und ls. Ein falsches Verzeichnis plus rm ist eine erstaunlich effiziente Form von Archäologie.
  • Nutze die TAB-Vervollständigung. Sie ist schneller und produziert weniger Tippfehler.
  • Benutze die Befehlshistorie. , history und Ctrl+R sparen enorm viel Tipparbeit.
  • Logs zuerst lesen, dann spekulieren. journalctl, tail und grep beantworten viele Fragen nüchterner als Bauchgefühl.
  • sudo sparsam einsetzen. Administratorrechte sind Werkzeug, keine Standardbetriebsart.
  • Python-Projekte in virtuelle Umgebungen packen. Das verhindert ein allmähliches Abgleiten in die Dependency-Anarchie.
  • Für dauerhaft laufende Programme systemd verwenden. Ein Script mit & zu starten ist praktisch für Tests, aber noch kein sauberer Dienst.
  • Für Remote-Arbeit SSH-Schlüssel verwenden. Das ist bequemer und bei vernünftiger Konfiguration sicherer als ständig Passwörter einzutippen.
  • Vor Änderungen an wichtigen Konfigurationen ein Backup machen. Zum Beispiel: sudo cp /etc/config /etc/config.bak.
  • Wenn du einen Befehl nicht verstehst: nicht ausführen – zerlegen. Prüfe Programm, Optionen, Argumente und Umleitungen einzeln.

73. Die 20 Befehle, die man zuerst wirklich können sollte

pwd                         # Wo bin ich?
ls -lah                     # Was ist hier?
cd VERZEICHNIS              # Verzeichnis wechseln
mkdir VERZEICHNIS           # Verzeichnis erstellen
cp QUELLE ZIEL              # Kopieren
mv QUELLE ZIEL              # Verschieben / Umbenennen
rm DATEI                    # Datei löschen
nano DATEI                  # Datei bearbeiten
less DATEI                  # Datei lesen
tail -f LOGDATEI            # Log live beobachten
grep "TEXT" DATEI           # Text suchen
find . -name "DATEI"        # Datei suchen
ps aux                      # Prozesse anzeigen
top                         # Systemlast beobachten
systemctl status DIENST     # Dienst prüfen
journalctl -u DIENST        # Dienst-Logs
ip a                        # Netzwerk anzeigen
ssh USER@HOST               # Remote-Verbindung
sudo apt update             # Paketlisten aktualisieren
man BEFEHL                  # Hilfe lesen

74. Beispiel: Raspberry Pi vom Einschalten bis zum laufenden Sensorprojekt

1. Verbindung herstellen

ssh julian@raspberrypi.local

2. Systemzustand prüfen

hostname
hostname -I
uptime
df -h
free -h

3. I²C prüfen

i2cdetect -y 1

4. Projekt öffnen

cd ~/bme280_logger
ls -lah

5. Python-Umgebung aktivieren

source .venv/bin/activate

6. Programm testen

python logger.py

7. Bei Problemen Logs bzw. Prozesse prüfen

ps aux | grep logger
journalctl -b -p err

8. Falls das Projekt als systemd-Dienst läuft

systemctl status bme280-logger
journalctl -u bme280-logger -f

9. Raspberry Pi sauber herunterfahren

sudo shutdown -h now

75. Was man eigentlich lernen sollte

Man muss nicht hunderte Linux-Befehle auswendig kennen. Wichtiger ist zu verstehen, wie das System denkt: Dateien besitzen Pfade und Rechte, Programme sind Prozesse, Prozesse erzeugen Ein- und Ausgaben, Dienste werden vom Init-System verwaltet, Hardware erscheint über Schnittstellen im Dateisystem, und kleine Werkzeuge lassen sich über Pipes miteinander verbinden.

Ab diesem Punkt verändert sich die Kommandozeile. Sie ist nicht länger eine kryptische schwarze Fläche, in die man Befehle aus Stack-Overflow-Grabungen kopiert, sondern eine ziemlich präzise Sprache zur Beschreibung dessen, was der Rechner tun soll.

Die drei vielleicht wichtigsten Linux-Kommandos bleiben trotzdem: man, --help und ein kurzer Moment des Nachdenkens vor sudo.

↑ top

↑ top


Linux · Raspberry Pi · SSH

SSH-Key auf Windows, Tablet und Raspberry Pi einrichten

SSH-Schlüssel wirken am Anfang wie dunkle Konsolenmagie. Tatsächlich ist das Prinzip einfach: Der private Schlüssel bleibt auf dem eigenen Gerät, der öffentliche Schlüssel kommt auf jene Geräte, auf die man sich anmelden möchte.

Inhalte

1. Grundprinzip: privater und öffentlicher Schlüssel

Ein SSH-Key besteht immer aus zwei Teilen: einem privaten Schlüssel und einem öffentlichen Schlüssel.

Privater Schlüssel

Der private Schlüssel bleibt ausschließlich auf dem eigenen Gerät, also zum Beispiel auf dem Stand-PC, Laptop oder Tablet. Er ist der eigentliche Haustürschlüssel und darf nicht weitergegeben oder auf fremde Geräte kopiert werden.

~/.ssh/id_ed25519

Öffentlicher Schlüssel

Der öffentliche Schlüssel darf auf Zielgeräte kopiert werden, etwa auf einen Raspberry Pi, einen Server oder ein anderes Linux-System mit SSH-Zugang.

~/.ssh/id_ed25519.pub

Auf dem Zielgerät wird dieser öffentliche Schlüssel in die Datei authorized_keys eingetragen:

~/.ssh/authorized_keys

Diese Datei ist gewissermaßen die Gästeliste des Zielsystems. Jeder dort eingetragene öffentliche Schlüssel darf sich anmelden, sofern der passende private Schlüssel auf dem Client vorhanden ist.

2. Braucht jedes Remote-Gerät einen eigenen Schlüssel?

Nicht zwingend. Sinnvoll ist meist folgende Regel:

Ein Client-Gerät = ein eigenes Schlüsselpaar.
    Ein Remote-Gerät = enthält die erlaubten öffentlichen Schlüssel.

Beispiel:

  • Der Stand-PC hat seinen eigenen privaten und öffentlichen Schlüssel.
  • Das Tablet hat ebenfalls seinen eigenen privaten und öffentlichen Schlüssel.
  • Der Raspberry Pi enthält in authorized_keys beide öffentlichen Schlüssel.

Dadurch können sich sowohl Stand-PC als auch Tablet am Raspberry Pi anmelden, ohne dass private Schlüssel zwischen Geräten herumkopiert werden müssen.

3. Prüfen, ob auf Windows bereits ein SSH-Key vorhanden ist

Unter Windows funktioniert der Linux-Befehl ls -la in der klassischen PowerShell nicht wie erwartet. PowerShell kennt zwar ls als Alias, aber nicht die Linux-Option -la.

Der Versuch führt daher zu einer Fehlermeldung wie:

Get-ChildItem : Es wurde kein Parameter gefunden,
der dem Parameternamen "la" entspricht.

Stattdessen verwendet man unter Windows PowerShell:

dir $env:USERPROFILE\.ssh

Oder gezielt für ED25519-Schlüssel:

dir $env:USERPROFILE\.ssh\id_ed25519*

Wenn Dateien wie diese vorhanden sind, existiert bereits ein SSH-Key:

id_ed25519
id_ed25519.pub

Der öffentliche Schlüssel kann mit folgendem Befehl angezeigt werden:

cat ~/.ssh/id_ed25519.pub

Die Ausgabe sieht ungefähr so aus:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... benutzer@example.com

Diese Zeile darf auf das Zielgerät kopiert werden. Der private Schlüssel id_ed25519 bleibt dagegen auf dem Windows-PC.

4. Verbindung zum Raspberry Pi testen

Wenn der Raspberry Pi im Netzwerk unter dem Hostnamen sailsense.local erreichbar ist und der Benutzer user heißt, lautet der SSH-Befehl:

ssh user@sailsense.local

Beim ersten Verbindungsaufbau erscheint normalerweise eine Meldung wie:

The authenticity of host 'sailsense.local' can't be established.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Diese Meldung bedeutet: Der Computer kennt dieses Zielgerät noch nicht. Wenn man sicher ist, dass es sich um den eigenen Raspberry Pi handelt, bestätigt man mit:

yes

Danach wird der Raspberry Pi in die Datei known_hosts eingetragen.

Wenn anschließend noch nach dem Passwort gefragt wird, ist der SSH-Key noch nicht richtig eingerichtet oder wird vom Raspberry Pi noch nicht akzeptiert.

5. Öffentlichen Schlüssel auf dem Raspberry Pi eintragen

Auf dem Raspberry Pi muss der öffentliche Schlüssel des Windows-PCs oder Tablets in die Datei authorized_keys eingetragen werden.

Zuerst am Raspberry Pi einloggen:

ssh user@sailsense.local

Dann das SSH-Verzeichnis anlegen beziehungsweise absichern:

mkdir -p ~/.ssh
chmod 700 ~/.ssh

Nun die Datei authorized_keys öffnen:

nano ~/.ssh/authorized_keys

Dort wird der öffentliche Schlüssel eingefügt. Eine solche Datei kann zum Beispiel so aussehen:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... standpc@example.com
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... [tablet@example.com](mailto:tablet@example.com)

Wichtig: Jeder öffentliche Schlüssel steht in einer eigenen Zeile.

Danach werden die Dateirechte gesetzt:

chmod 600 ~/.ssh/authorized_keys
6. Der typische Fehler: falsche Rechte auf ~/.ssh

Ein häufiger Fehler ist dieser Befehl:

chmod 600 ~/.ssh

Das sieht harmlos aus, ist aber falsch. ~/.ssh ist ein Ordner. Ein Ordner braucht Ausführungsrechte, damit er betreten werden kann. Ohne dieses Recht kann SSH die Datei authorized_keys nicht zuverlässig lesen.

Die Folge kann eine merkwürdige Ausgabe sein:

ls: cannot access '/home/user/.ssh/authorized_keys': Permission denied
d????????? ? ? ? ? ? .
-????????? ? ? ? ? ? authorized_keys

Das bedeutet sinngemäß: Das System sieht, dass dort etwas liegt, darf aber nicht sauber darauf zugreifen. SSH fällt dann auf die Passwortabfrage zurück.

Die korrekten Rechte lauten:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Zusätzlich kann man sicherstellen, dass der Benutzer auch wirklich Eigentümer der Dateien ist:

chown -R user:user ~/.ssh

Danach sollte die Kontrolle so aussehen:

ls -la ~/.ssh

Erwartete Ausgabe:

drwx------ 2 user user 4096 ... .
drwx------ 7 user user 4096 ... ..
-rw------- 1 user user  211 ... authorized_keys

Merksatz:

.ssh              → 700
authorized_keys   → 600

7. Warum fragt SSH trotz eingetragenem Schlüssel noch nach dem Passwort?

Wenn SSH weiterhin nach dem Passwort fragt, obwohl der öffentliche Schlüssel eingetragen wurde, kommen meist diese Ursachen infrage:

  • Die Rechte von ~/.ssh oder authorized_keys sind falsch.
  • Der öffentliche Schlüssel wurde in die falsche Benutzerkennung eingetragen.
  • Der eingetragene öffentliche Schlüssel passt nicht zum privaten Schlüssel des Client-Geräts.
  • Der SSH-Client verwendet einen anderen Schlüssel als erwartet.
  • Der Inhalt von authorized_keys wurde beschädigt, etwa durch Zeilenumbrüche mitten im Schlüssel.

Wichtig ist besonders der Benutzername. Wer sich so verbindet:

ssh user@sailsense.local

muss den Schlüssel hier eintragen:

/home/user/.ssh/authorized_keys

Würde man sich als pi anmelden, müsste der Schlüssel stattdessen in:

/home/pi/.ssh/authorized_keys

SSH ist hier pedantisch. Verschiedene Benutzer sind verschiedene Türen.

8. Verbindung mit Debug-Ausgabe prüfen

Wenn unklar ist, welcher Schlüssel verwendet wird, hilft die Debug-Ausgabe:

ssh -v user@sailsense.local

Interessant sind Zeilen wie:

Offering public key: C:\Users\julka\.ssh\id_ed25519

Das bedeutet: Der Client bietet diesen Schlüssel an.

Ideal wäre danach eine Meldung wie:

Server accepts key

Wenn der Schlüssel angeboten, aber nicht akzeptiert wird, liegt das Problem fast immer auf dem Zielgerät: falscher Eintrag, falscher Benutzer, falsche Rechte oder falscher Besitzer.

Man kann einen bestimmten Schlüssel auch ausdrücklich angeben:

ssh -i $env:USERPROFILE\.ssh\id_ed25519 user@sailsense.local

9. SSH-Key vom Tablet auf den Raspberry Pi einrichten

Auf einem Tablet hängt die genaue Vorgehensweise vom System ab. Unter Android wird häufig Termux verwendet. Dort kann man wie unter Linux arbeiten.

Zuerst prüfen, ob schon ein Schlüssel vorhanden ist:

ls -la ~/.ssh

Falls noch kein Schlüssel vorhanden ist, erzeugt man einen neuen:

ssh-keygen -t ed25519 -C "tablet"

Der Standardpfad kann in der Regel mit Enter übernommen werden:

~/.ssh/id_ed25519

Danach wird der öffentliche Schlüssel angezeigt:

cat ~/.ssh/id_ed25519.pub

Diese komplette Zeile wird anschließend auf dem Raspberry Pi in ~/.ssh/authorized_keys eingefügt.

Auf dem Raspberry Pi:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Danach kann vom Tablet getestet werden:

ssh user@sailsense.local

10. Praktische SSH-Konfiguration

Damit man nicht jedes Mal den vollständigen Hostnamen und Benutzernamen eintippen muss, kann man auf dem Client eine SSH-Konfiguration anlegen.

Unter Linux, macOS oder Termux:

nano ~/.ssh/config

Unter Windows liegt die Datei hier:

C:\Users\BENUTZERNAME\.ssh\config

Beispielinhalt:

Host sailsense
HostName sailsense.local
User user
IdentityFile ~/.ssh/id_ed25519

Danach genügt:

ssh sailsense

Falls sailsense.local im Netzwerk nicht zuverlässig aufgelöst wird, kann statt des Hostnamens auch die IP-Adresse eingetragen werden:

Host sailsense
HostName 192.168.1.123
User user
IdentityFile ~/.ssh/id_ed25519

11. Passwortlogin erst später deaktivieren

Der Passwortlogin sollte erst deaktiviert werden, wenn die Anmeldung per SSH-Key sicher funktioniert. Sonst sperrt man sich schlimmstenfalls selbst aus. Das ist kein Sicherheitskonzept, sondern ein digitaler Tritt auf die eigene Harke.

Erst wenn der Login ohne Raspberry-Passwort funktioniert, kann man die SSH-Konfiguration bearbeiten:

sudo nano /etc/ssh/sshd_config

Dort setzt man:

PasswordAuthentication no

Danach wird SSH neu gestartet:

sudo systemctl restart ssh

Wichtig: Vorher ein zweites Terminal offen lassen und testen, ob der Key-Login wirklich funktioniert.

12. Kurzfassung

  • Der private Schlüssel bleibt auf dem eigenen Gerät.
  • Der öffentliche Schlüssel kommt auf das Zielgerät.
  • Auf dem Zielgerät steht der öffentliche Schlüssel in ~/.ssh/authorized_keys.
  • Der Ordner ~/.ssh braucht die Rechte 700.
  • Die Datei authorized_keys braucht die Rechte 600.
  • Ein versehentliches chmod 600 ~/.ssh macht den Ordner unbetretbar.
  • Wenn SSH weiter nach dem Passwort fragt, mit ssh -v debuggen.

Für das konkrete Raspberry-Pi-Setup lautet die wichtigste Reparatur:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R user:user ~/.ssh

Danach sollte der Login vom Windows-PC oder Tablet per SSH-Key funktionieren.

↑ top


Raspberry Pi Services mit systemd: Autostart, Kontrolle und Fehlersuche

Ein Raspberry Pi läuft oft ohne Bildschirm, Tastatur und Maus. Gerade bei Loggern, Sensorstationen, Heimautomationsprojekten oder kleinen Serverdiensten soll ein Programm automatisch starten, sobald der Pi hochfährt. Genau dafür verwendet man unter Raspberry Pi OS in der Regel systemd-Services.

Ein Service ist ein Hintergrunddienst: ein Programm, das vom Betriebssystem gestartet, überwacht, gestoppt und bei Bedarf automatisch neu gestartet werden kann. Statt ein Python-Skript nach jedem Neustart händisch per SSH zu starten, übernimmt systemd diese Aufgabe zuverlässig.

Was ist systemd?

systemd ist das Start- und Diensteverwaltungssystem vieler moderner Linux-Distributionen, darunter auch Raspberry Pi OS. Es kümmert sich darum, welche Prozesse beim Booten gestartet werden, in welcher Reihenfolge sie starten und wie sie überwacht werden.

Für eigene Projekte bedeutet das: Man schreibt eine kleine Service-Datei, legt darin fest, welches Programm gestartet werden soll, unter welchem Benutzer es laufen soll und was passieren soll, wenn es abstürzt.

Typische Einsatzfälle

  • Ein Python-Logger soll beim Booten automatisch starten.
  • Ein Webserver soll dauerhaft im Hintergrund laufen.
  • Ein Sensorprogramm soll nach einem Absturz neu gestartet werden.
  • Ein OLED-Display, GPS-Modul oder Wetterlogger soll ohne manuelles Eingreifen laufen.
  • Ein Raspberry Pi soll als headless Bordcomputer, Server oder Messgerät arbeiten.

Wichtige Begriffe

  • Unit: Allgemeine systemd-Konfigurationsdatei, z. B. Service, Timer oder Mount.
  • Service: Eine Unit, die ein Programm oder Skript startet.
  • Enable: Service wird beim Booten automatisch gestartet.
  • Start: Service wird jetzt sofort gestartet.
  • Stop: Service wird jetzt gestoppt.
  • Restart: Service wird neu gestartet.
  • Status: Aktueller Zustand des Services.
  • Journal: systemd-Logausgabe, abrufbar über journalctl.

Wo liegen eigene Service-Dateien?

Eigene systemd-Service-Dateien legt man üblicherweise hier ab:

/etc/systemd/system/

Beispiel:

/etc/systemd/system/sailsense.service

Der Dateiname ist gleichzeitig der Servicename. Aus sailsense.service wird also:

systemctl status sailsense.service

Beispiel: Python-App als Service starten

Angenommen, das Projekt liegt unter:

/home/user/sailsense

Die virtuelle Python-Umgebung liegt unter:

/home/user/sailsense/.venv

Und die App wird manuell so gestartet:

cd /home/user/sailsense
source .venv/bin/activate
PYTHONPATH=src python -m sailsense.app

Dann kann die passende Service-Datei so aussehen:

[Unit]
Description=SailSense GPS Weather Logger
After=multi-user.target

[Service]
Type=simple
User=user
Group=user
SupplementaryGroups=dialout i2c gpio
WorkingDirectory=/home/user/sailsense
Environment=PYTHONPATH=/home/user/sailsense/src
ExecStart=/home/user/sailsense/.venv/bin/python -m sailsense.app
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Service-Datei anlegen

Eine neue Service-Datei erstellt man zum Beispiel mit:

sudo nano /etc/systemd/system/sailsense.service

Danach den Inhalt einfügen, speichern und schließen.

Aufbau einer Service-Datei

[Unit]

Der Abschnitt [Unit] beschreibt den Dienst und seine Abhängigkeiten.

[Unit]
Description=SailSense GPS Weather Logger
After=multi-user.target
  • Description: Kurzbeschreibung des Dienstes.
  • After: Gibt an, nach welchem Ziel oder Dienst dieser Service gestartet werden soll.

[Service]

Der Abschnitt [Service] legt fest, was genau gestartet wird.

[Service]
Type=simple
User=user
Group=user
SupplementaryGroups=dialout i2c gpio
WorkingDirectory=/home/user/sailsense
Environment=PYTHONPATH=/home/user/sailsense/src
ExecStart=/home/user/sailsense/.venv/bin/python -m sailsense.app
Restart=on-failure
RestartSec=5
  • Type=simple: Der gestartete Prozess bleibt im Vordergrund und ist der Service.
  • User: Benutzer, unter dem das Programm läuft.
  • Group: Hauptgruppe des Prozesses.
  • SupplementaryGroups: Zusätzliche Gruppen, etwa für GPIO, I²C oder serielle Schnittstellen.
  • WorkingDirectory: Arbeitsverzeichnis des Programms.
  • Environment: Umgebungsvariable, hier z. B. PYTHONPATH.
  • ExecStart: Der eigentliche Startbefehl.
  • Restart=on-failure: Bei Fehler automatisch neu starten.
  • RestartSec=5: Fünf Sekunden warten, bevor neu gestartet wird.

[Install]

Der Abschnitt [Install] legt fest, wann der Dienst beim Booten aktiviert wird.

[Install]
WantedBy=multi-user.target

multi-user.target entspricht grob einem normalen Mehrbenutzerbetrieb ohne grafische Oberfläche. Für headless Raspberry-Pi-Projekte ist das meistens passend.

systemd nach Änderungen neu laden

Nach jeder Änderung an einer Service-Datei muss systemd seine Konfiguration neu einlesen:

sudo systemctl daemon-reload

Wenn man das vergisst, arbeitet systemd eventuell noch mit der alten Version der Datei. Das ist einer dieser kleinen Linux-Stolperdrähte, über die jeder einmal mit Würde fällt.

Service sofort starten

sudo systemctl start sailsense.service

Das startet den Service sofort, aber noch nicht automatisch beim nächsten Boot.

Service stoppen

sudo systemctl stop sailsense.service

Das stoppt den laufenden Dienst. Praktisch, wenn man am Code arbeiten möchte.

Service neu starten

sudo systemctl restart sailsense.service

Das ist nützlich nach Codeänderungen oder Konfigurationsänderungen.

Status abfragen

systemctl status sailsense.service

Typische Ausgabe:

● sailsense.service - SailSense GPS Weather Logger
     Loaded: loaded (/etc/systemd/system/sailsense.service; enabled)
     Active: active (running)
   Main PID: 1234 (python)
      Tasks: 5
     Memory: 42.0M

Wichtig ist vor allem die Zeile:

Active: active (running)

Das bedeutet: Der Service läuft.

Kurz prüfen, ob ein Service läuft

systemctl is-active sailsense.service

Mögliche Ausgaben:

  • active: läuft.
  • inactive: läuft nicht.
  • failed: ist fehlgeschlagen.

Autostart aktivieren

sudo systemctl enable sailsense.service

Damit wird der Dienst beim nächsten Boot automatisch gestartet.

Autostart deaktivieren

sudo systemctl disable sailsense.service

Der Dienst bleibt installierbar und kann manuell gestartet werden, startet aber nicht mehr automatisch beim Booten.

Prüfen, ob Autostart aktiv ist

systemctl is-enabled sailsense.service

Mögliche Ausgaben:

  • enabled: startet automatisch.
  • disabled: startet nicht automatisch.
  • static: kann nicht direkt aktiviert werden, wird aber möglicherweise von anderen Units verwendet.

Logs ansehen

systemd sammelt die Ausgaben eines Services im Journal. Alles, was das Programm mit print() ausgibt, kann dort erscheinen.

Live-Log

journalctl -u sailsense.service -f

-f bedeutet: neue Ausgaben live verfolgen. Beenden mit Strg+C.

Letzte 80 Zeilen

journalctl -u sailsense.service -n 80 --no-pager

Logs seit dem letzten Boot

journalctl -u sailsense.service -b --no-pager

Logs mit Zeitstempel

journalctl -u sailsense.service -n 100 --no-pager -o short-iso

Fehlerzustand zurücksetzen

Wenn ein Service fehlgeschlagen ist, kann systemd ihn als failed markieren. Nach der Fehlerbehebung kann man diesen Zustand zurücksetzen:

sudo systemctl reset-failed sailsense.service

Service-Datei überprüfen

Vor dem Start kann man die Service-Datei formal prüfen:

sudo systemd-analyze verify /etc/systemd/system/sailsense.service

Keine Ausgabe ist hier meist eine gute Nachricht.

Typischer Ablauf nach Änderung einer Service-Datei

sudo nano /etc/systemd/system/sailsense.service
sudo systemctl daemon-reload
sudo systemd-analyze verify /etc/systemd/system/sailsense.service
sudo systemctl restart sailsense.service
systemctl status sailsense.service

Typischer Ablauf nach Änderung des Python-Codes

Wenn nur der Python-Code geändert wurde, nicht die Service-Datei:

sudo systemctl restart sailsense.service
journalctl -u sailsense.service -n 80 --no-pager

Service beim Entwickeln deaktivieren

Wenn man an der App arbeitet, ist es oft sinnvoll, den Service vorübergehend zu stoppen:

sudo systemctl stop sailsense.service

Wenn man verhindern will, dass er beim nächsten Boot automatisch startet:

sudo systemctl disable sailsense.service

Danach kann man die App manuell starten:

cd /home/user/sailsense
source .venv/bin/activate
PYTHONPATH=src python -m sailsense.app

Service wieder aktivieren

sudo systemctl enable sailsense.service
sudo systemctl start sailsense.service

Häufige Fehler

1. Service-Datei hat falsche Abschnitte

Fehlerbild:

Assignment outside of section

Ursache: In der Service-Datei fehlt wahrscheinlich ein Abschnitt wie [Unit], [Service] oder [Install].

2. ExecStart fehlt

Fehlerbild:

Service has no ExecStart=

Ursache: Im Abschnitt [Service] fehlt der Startbefehl.

3. Falscher Python-Pfad

Fehlerbild:

No such file or directory

Prüfen:

ls -l /home/user/sailsense/.venv/bin/python

4. Modul wird nicht gefunden

Fehlerbild:

ModuleNotFoundError

Ursache: Häufig fehlt PYTHONPATH.

In der Service-Datei:

Environment=PYTHONPATH=/home/user/sailsense/src

5. Zugriff auf GPIO, I²C oder serielle Schnittstelle fehlt

Fehlerbild:

Permission denied

Lösung: Benutzer in die nötigen Gruppen aufnehmen oder im Service zusätzliche Gruppen setzen.

SupplementaryGroups=dialout i2c gpio

Danach:

sudo systemctl daemon-reload
sudo systemctl restart sailsense.service

6. Service startet zu früh

Manchmal startet ein Dienst, bevor Hardware oder Netzwerk bereit ist.

Beispiele:

After=network-online.target
Wants=network-online.target

Für Hardwareuhren oder spezielle Geräte können eigene Abhängigkeiten sinnvoll sein, zum Beispiel:

Wants=rtc-hwclock.service
After=rtc-hwclock.service multi-user.target

Beispiel: Service mit RTC-Abhängigkeit

Wenn ein Projekt eine RTC verwendet, kann man sicherstellen, dass zuerst die Systemzeit aus der Hardware-Uhr gelesen wird.

[Unit]
Description=SailSense GPS Weather Logger
Wants=rtc-hwclock.service
After=rtc-hwclock.service multi-user.target

[Service]
Type=simple
User=user
Group=user
SupplementaryGroups=dialout i2c gpio
WorkingDirectory=/home/user/sailsense
Environment=PYTHONPATH=/home/user/sailsense/src
ExecStart=/home/user/sailsense/.venv/bin/python -m sailsense.app
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Cheat Sheet: wichtigste Befehle

Aufgabe Befehl
Status anzeigen systemctl status sailsense.service
Starten sudo systemctl start sailsense.service
Stoppen sudo systemctl stop sailsense.service
Neu starten sudo systemctl restart sailsense.service
Autostart aktivieren sudo systemctl enable sailsense.service
Autostart deaktivieren sudo systemctl disable sailsense.service
Prüfen, ob aktiv systemctl is-active sailsense.service
Prüfen, ob Autostart aktiv systemctl is-enabled sailsense.service
Live-Log anzeigen journalctl -u sailsense.service -f
Letzte Logs anzeigen journalctl -u sailsense.service -n 80 --no-pager
systemd neu laden sudo systemctl daemon-reload
Service-Datei prüfen sudo systemd-analyze verify /etc/systemd/system/sailsense.service
Fehlerzustand zurücksetzen sudo systemctl reset-failed sailsense.service

Minimaler Wartungsablauf für eigene Raspberry-Pi-Projekte

  1. Service stoppen: sudo systemctl stop sailsense.service
  2. Code bearbeiten.
  3. App manuell testen.
  4. Service neu starten: sudo systemctl restart sailsense.service
  5. Status prüfen: systemctl status sailsense.service
  6. Logs prüfen: journalctl -u sailsense.service -n 80 --no-pager

Merksatz

Start startet jetzt. Enable startet künftig beim Booten. Status sagt, ob es lebt. Journalctl sagt, warum es gestorben ist.


↑ top⌂ home← back