merging and cleaning up
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
Unten eine vollständige, schrittweise Anleitung (auf Deutsch), wie du eine AppImage unter /opt ablegst, ins Startmenü einbindest und optional ein Icon extrahierst. Ich gebe dir Beispielbefehle — ersetze die Platzhalter durch den echten Dateinamen/deine App-Namen.
|
||||
|
||||
Voraussetzungen
|
||||
- Du brauchst sudo-Rechte.
|
||||
- AppImage-Datei (z. B. ExampleApp.AppImage) ist im Downloads-Ordner.
|
||||
|
||||
Schritt 1 — AppImage ausführbar machen
|
||||
Öffne ein Terminal und mache die Datei ausführbar:
|
||||
```
|
||||
cd ~/Downloads
|
||||
chmod +x ExampleApp.AppImage
|
||||
```
|
||||
|
||||
Schritt 2 — AppImage nach /opt verschieben
|
||||
Erstelle ein Unterverzeichnis unter /opt (z. B. /opt/exampleapp) und verschiebe die AppImage dort hin:
|
||||
```
|
||||
sudo mkdir -p /opt/exampleapp
|
||||
sudo mv ExampleApp.AppImage /opt/exampleapp/
|
||||
sudo chown -R root:root /opt/exampleapp
|
||||
```
|
||||
Optional: Um den Namen konsistent zu halten, kannst du die Datei umbenennen:
|
||||
```
|
||||
sudo mv /opt/exampleapp/ExampleApp.AppImage /opt/exampleapp/exampleapp.AppImage
|
||||
```
|
||||
|
||||
Schritt 3 — Einfachen Startbefehl anlegen (Symlink oder Wrapper)
|
||||
Damit die App systemweit mit kurzem Namen startet, lege einen Symlink oder ein kleines Wrapper-Skript in /usr/local/bin an.
|
||||
|
||||
Variante A — Symlink:
|
||||
```
|
||||
sudo ln -s /opt/exampleapp/exampleapp.AppImage /usr/local/bin/exampleapp
|
||||
sudo chmod +x /usr/local/bin/exampleapp
|
||||
```
|
||||
|
||||
Variante B — Wrapper-Skript (empfohlen, falls Argumente weitergeleitet werden sollen):
|
||||
```
|
||||
sudo tee /usr/local/bin/exampleapp > /dev/null <<'EOF'
|
||||
#!/bin/sh
|
||||
exec /opt/exampleapp/exampleapp.AppImage "$@"
|
||||
EOF
|
||||
sudo chmod +x /usr/local/bin/exampleapp
|
||||
```
|
||||
|
||||
Schritt 4 — Icon aus dem AppImage extrahieren (optional, aber empfohlen)
|
||||
Viele AppImages haben ein eingebettetes Icon (.DirIcon) oder eine .png-Datei. So extrahierst du es:
|
||||
```
|
||||
cd /tmp
|
||||
/opt/exampleapp/exampleapp.AppImage --appimage-extract
|
||||
# die extrahierten Dateien liegen jetzt in /tmp/squashfs-root
|
||||
```
|
||||
Suche das Icon:
|
||||
```
|
||||
ls squashfs-root | grep -i DirIcon || ls squashfs-root | grep -i png
|
||||
```
|
||||
Beispiel: wenn squashfs-root/.DirIcon vorhanden ist, kopiere es als PNG in die Icon-Hierarchie:
|
||||
```
|
||||
sudo mkdir -p /usr/share/icons/hicolor/256x256/apps
|
||||
sudo cp squashfs-root/.DirIcon /usr/share/icons/hicolor/256x256/apps/exampleapp.png
|
||||
sudo chmod 644 /usr/share/icons/hicolor/256x256/apps/exampleapp.png
|
||||
```
|
||||
(Optional) Icon-Cache aktualisieren:
|
||||
```
|
||||
sudo gtk-update-icon-cache /usr/share/icons/hicolor
|
||||
```
|
||||
Aufräumen:
|
||||
```
|
||||
rm -rf /tmp/squashfs-root
|
||||
```
|
||||
|
||||
Hinweis: Wenn du die App nur für deinen Benutzer installierst, kopiere das Icon nach ~/.local/share/icons/hicolor/256x256/apps/ statt /usr/share/...
|
||||
|
||||
Schritt 5 — .desktop-Datei anlegen (Startmenü-Eintrag)
|
||||
Siehe auch hier: [[Linux .desktop Dateien]]
|
||||
Systemweit (für alle Benutzer):
|
||||
```
|
||||
sudo tee /usr/share/applications/exampleapp.desktop > /dev/null <<'EOF'
|
||||
[Desktop Entry]
|
||||
Name=ExampleApp
|
||||
GenericName=Example Application
|
||||
Comment=Beschreibung der Anwendung
|
||||
Exec=/usr/local/bin/exampleapp %U
|
||||
Icon=exampleapp
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Utility;Application;
|
||||
StartupWMClass=ExampleApp
|
||||
EOF
|
||||
```
|
||||
|
||||
Alternativ für nur deinen Benutzer:
|
||||
```
|
||||
mkdir -p ~/.local/share/applications
|
||||
tee ~/.local/share/applications/exampleapp.desktop > /dev/null <<'EOF'
|
||||
[Desktop Entry]
|
||||
Name=ExampleApp
|
||||
GenericName=Example Application
|
||||
Comment=Beschreibung der Anwendung
|
||||
Exec=/usr/local/bin/exampleapp %U
|
||||
Icon=/home/deinuser/.local/share/icons/hicolor/256x256/apps/exampleapp.png
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Utility;Application;
|
||||
StartupWMClass=ExampleApp
|
||||
EOF
|
||||
```
|
||||
Wichtige Felder:
|
||||
- Exec: Pfad zur ausführbaren Datei oder zu deinem Symlink (/usr/local/bin/exampleapp). %U erlaubt URLs/Dateien als Argumente.
|
||||
- Icon: entweder der einfache Icon-Name (ohne Endung), wenn du das Icon in /usr/share/icons/hicolor abgelegt hast, oder ein voller Pfad.
|
||||
- Categories: für die Kategorisierung im Menü (z. B. Utility, Development, Office).
|
||||
- Terminal=false, falls kein Terminal nötig.
|
||||
|
||||
Setze die richtigen Rechte:
|
||||
```
|
||||
sudo chmod 644 /usr/share/applications/exampleapp.desktop
|
||||
# oder für user:
|
||||
chmod 644 ~/.local/share/applications/exampleapp.desktop
|
||||
```
|
||||
|
||||
Schritt 6 — Desktop-Datenbank aktualisieren (falls nötig)
|
||||
Für Systemmenüs:
|
||||
```
|
||||
sudo update-desktop-database
|
||||
```
|
||||
Für GNOME/andere DEs: in der Regel reicht Aus- und Einloggen oder Neustart des Shells/Session.
|
||||
|
||||
Schritt 7 — Testen
|
||||
- Öffne dein Startmenü / Activities und suche nach "ExampleApp".
|
||||
- Alternativ im Terminal: `exampleapp` (oder `/opt/exampleapp/exampleapp.AppImage`).
|
||||
|
||||
Optionale Hinweise
|
||||
- Automatische Updates: Manche AppImages unterstützen AppImageUpdate (z. B. mit zsync) oder du kannst AppImageLauncher verwenden, das AppImage-Integration & Updates verwaltet.
|
||||
- Sicherheitsaspekt: AppImages laufen nicht automatisch in einem Sandbox; für zusätzliche Isolation kannst du firejail verwenden.
|
||||
- Entfernen: Entferne /opt/exampleapp, den Symlink und die .desktop/Icons, um die App rückstandsfrei zu löschen.
|
||||
|
||||
Kurzbeispiel (kompakt)
|
||||
Angenommen Datei heißt ExampleApp.AppImage in ~/Downloads und dein Benutzername ist user:
|
||||
```
|
||||
cd ~/Downloads
|
||||
chmod +x ExampleApp.AppImage
|
||||
sudo mkdir -p /opt/exampleapp
|
||||
sudo mv ExampleApp.AppImage /opt/exampleapp/exampleapp.AppImage
|
||||
sudo ln -s /opt/exampleapp/exampleapp.AppImage /usr/local/bin/exampleapp
|
||||
# Icon extrahieren (falls vorhanden)
|
||||
/opt/exampleapp/exampleapp.AppImage --appimage-extract
|
||||
sudo cp squashfs-root/.DirIcon /usr/share/icons/hicolor/256x256/apps/exampleapp.png
|
||||
rm -rf squashfs-root
|
||||
# .desktop anlegen
|
||||
sudo tee /usr/share/applications/exampleapp.desktop > /dev/null <<'EOF'
|
||||
[Desktop Entry]
|
||||
Name=ExampleApp
|
||||
Exec=/usr/local/bin/exampleapp %U
|
||||
Icon=exampleapp
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Categories=Utility;
|
||||
EOF
|
||||
sudo chmod 644 /usr/share/applications/exampleapp.desktop
|
||||
sudo update-desktop-database
|
||||
```
|
||||
|
||||
Wenn du willst, schreibe mir:
|
||||
- Wie die AppImage-Datei heißt, und
|
||||
- ob du die Installation systemweit (für alle Benutzer) oder nur für dich wünschst.
|
||||
Dann passe ich die Befehle genau für deine App an.
|
||||
@@ -0,0 +1,40 @@
|
||||
# BASH Basics - Übersicht
|
||||
|
||||
Sammlung wichtiger BASH-Befehle und Konzepte für die Linux-Konsole.
|
||||
|
||||
## Grundlegende Konzepte
|
||||
|
||||
- [[BASH Funktionen]] - Wiederverwendbare Funktionen erstellen
|
||||
|
||||
## Dateiverwaltung
|
||||
|
||||
- [[ls]] - Dateien auflisten und Größen anzeigen
|
||||
- [[find]] - Dateien suchen, filtern und verarbeiten (inkl. Datum, Löschen)
|
||||
- [[Symlinks]] - Symbolische Links erstellen und verwalten
|
||||
|
||||
## Textverarbeitung
|
||||
|
||||
- [[grep]] - Textsuche in Dateien
|
||||
- [[sed]] - Stream-Editor für Textmanipulation
|
||||
- [[awk]] - Datenextraktion und Spaltenverarbeitung
|
||||
|
||||
## Berechtigungen
|
||||
|
||||
- [[Dateiberechtigungen]] - chmod und chown (Rechte, Eigentümer, Gruppen)
|
||||
|
||||
## Archive und Backup
|
||||
|
||||
- [[tar]] - Archive erstellen/entpacken und Software installieren
|
||||
- [[rsync]] - Dateien synchronisieren
|
||||
|
||||
## System
|
||||
|
||||
- [[lsblk]] - Block-Geräte anzeigen
|
||||
- [[fstab Credentials]] - Zugangsdaten sicher in fstab speichern
|
||||
|
||||
## Verwandte Themen
|
||||
|
||||
Weitere Linux-Themen im übergeordneten Verzeichnis:
|
||||
- [[Linux]] - Allgemeine Linux-Dokumentation
|
||||
- [[SSH Verbindung in Linux]] - SSH-Verbindungen
|
||||
- [[Navidrome]] - Musik-Server
|
||||
@@ -0,0 +1,693 @@
|
||||
# BASH Funktionen# BASH FunktionenIn **[[Bash]]** kannst du wiederverwendbare **Funktionen** definieren, um Code übersichtlicher und modularer zu gestalten.
|
||||
|
||||
|
||||
|
||||
In BASH kannst du wiederverwendbare Funktionen definieren, um Code übersichtlicher und modularer zu gestalten.Hier ist eine kurze Einführung mit Beispielen 👇
|
||||
|
||||
|
||||
|
||||
## GrundsyntaxIn BASH kannst du wiederverwendbare Funktionen definieren, um Code übersichtlicher und modularer zu gestalten.
|
||||
|
||||
|
||||
|
||||
```bash---
|
||||
|
||||
meine_funktion() {
|
||||
|
||||
echo "Das ist eine wiederverwendbare Funktion!"## Grundsyntax
|
||||
|
||||
}
|
||||
|
||||
```### 🔹 **Grundsyntax einer Funktion**
|
||||
|
||||
|
||||
|
||||
Alternative Syntax (weniger üblich):```bash
|
||||
|
||||
|
||||
|
||||
```bashmeine_funktion() {```bash
|
||||
|
||||
function meine_funktion {
|
||||
|
||||
echo "Das ist eine wiederverwendbare Funktion!" echo "Das ist eine wiederverwendbare Funktion!"meine_funktion() {
|
||||
|
||||
}
|
||||
|
||||
```} echo "Das ist eine wiederverwendbare Funktion!"
|
||||
|
||||
|
||||
|
||||
## Funktion mit Parametern```}
|
||||
|
||||
|
||||
|
||||
In BASH werden Argumente positional übergeben: `$1`, `$2`, usw.```
|
||||
|
||||
|
||||
|
||||
```bashAlternative Syntax (weniger üblich):
|
||||
|
||||
begruesse() {
|
||||
|
||||
echo "Hallo $1!"Oder alternativ (weniger üblich, aber erlaubt):
|
||||
|
||||
}
|
||||
|
||||
```bash
|
||||
|
||||
begruesse "Anna"
|
||||
|
||||
# Ausgabe: Hallo Anna!function meine_funktion {```bash
|
||||
|
||||
```
|
||||
|
||||
echo "Das ist eine wiederverwendbare Funktion!"function meine_funktion {
|
||||
|
||||
## Rückgabewerte
|
||||
|
||||
} echo "Das ist eine wiederverwendbare Funktion!"
|
||||
|
||||
### Numerischer Exit-Code
|
||||
|
||||
```}
|
||||
|
||||
Eine Funktion kann mit `return` einen numerischen Exit-Code (0–255) zurückgeben:
|
||||
|
||||
```
|
||||
|
||||
```bash
|
||||
|
||||
teste_zahl() {## Funktion mit Parametern
|
||||
|
||||
if (( $1 > 10 )); then
|
||||
|
||||
return 0 # Erfolg---
|
||||
|
||||
else
|
||||
|
||||
return 1 # FehlerIn BASH werden Argumente positional übergeben: `$1`, `$2`, usw.
|
||||
|
||||
fi
|
||||
|
||||
}### 🔹 **Funktion mit Parametern**
|
||||
|
||||
|
||||
|
||||
if teste_zahl 15; then```bash
|
||||
|
||||
echo "Größer als 10"
|
||||
|
||||
elsebegruesse() {In Bash werden Argumente **positional** übergeben — also `$1`, `$2`, usw.
|
||||
|
||||
echo "Nicht größer als 10"
|
||||
|
||||
fi echo "Hallo $1!"
|
||||
|
||||
```
|
||||
|
||||
}```bash
|
||||
|
||||
### Text zurückgeben
|
||||
|
||||
begruesse() {
|
||||
|
||||
Um Text zurückzugeben, verwende `echo` oder `printf` und Command Substitution:
|
||||
|
||||
begruesse "Anna" echo "Hallo $1!"
|
||||
|
||||
```bash
|
||||
|
||||
addiere() {# Ausgabe: Hallo Anna!}
|
||||
|
||||
echo $(( $1 + $2 ))
|
||||
|
||||
}```
|
||||
|
||||
|
||||
|
||||
summe=$(addiere 3 5)begruesse "Anna"
|
||||
|
||||
echo "Summe: $summe" # Ausgabe: Summe: 8
|
||||
|
||||
```## Rückgabewerte# Ausgabe: Hallo Anna!
|
||||
|
||||
|
||||
|
||||
## Funktionen wiederverwendbar machen```
|
||||
|
||||
|
||||
|
||||
Speichere Funktionen in einer separaten Datei und lade sie mit `source`:### Numerischer Exit-Code
|
||||
|
||||
|
||||
|
||||
**funktionen.sh:**---
|
||||
|
||||
```bash
|
||||
|
||||
#!/bin/bashEine Funktion kann mit `return` einen numerischen Exit-Code (0–255) zurückgeben:
|
||||
|
||||
begruesse() {
|
||||
|
||||
echo "Hallo $1!"### 🔹 **Rückgabewerte**
|
||||
|
||||
}
|
||||
|
||||
``````bash
|
||||
|
||||
|
||||
|
||||
**hauptskript.sh:**teste_zahl() {- Eine Funktion kann mit `return` einen **numerischen Exit-Code** (0–255) zurückgeben.
|
||||
|
||||
```bash
|
||||
|
||||
#!/bin/bash if (( $1 > 10 )); then
|
||||
|
||||
source ./funktionen.sh
|
||||
|
||||
return 0 # Erfolg- Um Text zurückzugeben, verwendest du **`echo`** oder **`printf`** und fängst den Wert mit **Command Substitution** ein.
|
||||
|
||||
begruesse "Welt"
|
||||
|
||||
``` else
|
||||
|
||||
|
||||
|
||||
Alternative: `. ./funktionen.sh` return 1 # Fehler
|
||||
|
||||
|
||||
|
||||
## Lokale Variablen fi```bash
|
||||
|
||||
|
||||
|
||||
Verwende `local`, um Variablen nur innerhalb der Funktion sichtbar zu machen:}# numerischer Rückgabewert
|
||||
|
||||
|
||||
|
||||
```bashteste_zahl() {
|
||||
|
||||
addiere() {
|
||||
|
||||
local summe=$(( $1 + $2 ))if teste_zahl 15; then if (( $1 > 10 )); then
|
||||
|
||||
echo "$summe"
|
||||
|
||||
} echo "Größer als 10" return 0 # Erfolg
|
||||
|
||||
```
|
||||
|
||||
else else
|
||||
|
||||
## Default-Werte für Parameter
|
||||
|
||||
echo "Nicht größer als 10" return 1 # Fehler
|
||||
|
||||
```bash
|
||||
|
||||
mein_script() {fi fi
|
||||
|
||||
local name="${1:-Welt}" # Standardwert 'Welt'
|
||||
|
||||
local sprache="${2:-de}" # Standardwert 'de'```}
|
||||
|
||||
|
||||
|
||||
echo "Name: $name, Sprache: $sprache"
|
||||
|
||||
}
|
||||
|
||||
### Text zurückgebenif teste_zahl 15; then
|
||||
|
||||
mein_script "Anna" "en" # Name: Anna, Sprache: en
|
||||
|
||||
mein_script "Bob" # Name: Bob, Sprache: de echo "Größer als 10"
|
||||
|
||||
```
|
||||
|
||||
Um Text zurückzugeben, verwende `echo` oder `printf` und Command Substitution:else
|
||||
|
||||
## Benannte Argumente simulieren
|
||||
|
||||
echo "Nicht größer als 10"
|
||||
|
||||
### Mit case und Schleife
|
||||
|
||||
```bashfi
|
||||
|
||||
```bash
|
||||
|
||||
begruesse() {addiere() {```
|
||||
|
||||
local name="Welt"
|
||||
|
||||
local sprache="de" echo $(( $1 + $2 ))
|
||||
|
||||
|
||||
|
||||
for arg in "$@"; do}```bash
|
||||
|
||||
case $arg in
|
||||
|
||||
--name=*)# Text zurückgeben
|
||||
|
||||
name="${arg#*=}"
|
||||
|
||||
;;summe=$(addiere 3 5)addiere() {
|
||||
|
||||
--sprache=*|--lang=*)
|
||||
|
||||
sprache="${arg#*=}"echo "Summe: $summe" # Ausgabe: Summe: 8 echo $(( $1 + $2 ))
|
||||
|
||||
;;
|
||||
|
||||
*)```}
|
||||
|
||||
echo "Unbekannte Option: $arg" >&2
|
||||
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
done## Funktionen wiederverwendbar machensumme=$(addiere 3 5)
|
||||
|
||||
|
||||
|
||||
echo "Hallo $name! (Sprache: $sprache)"echo "Summe: $summe"
|
||||
|
||||
}
|
||||
|
||||
Speichere Funktionen in einer separaten Datei und lade sie mit `source`:# Ausgabe: Summe: 8
|
||||
|
||||
begruesse --name=Anna --sprache=en
|
||||
|
||||
``````
|
||||
|
||||
|
||||
|
||||
**Vorteile:****funktionen.sh:**
|
||||
|
||||
- Reihenfolge der Argumente ist egal
|
||||
|
||||
- Default-Werte bleiben bestehen```bash---
|
||||
|
||||
- Sehr gut lesbar
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
### Mit assoziativem Array
|
||||
|
||||
begruesse() {### 🔹 **Wiederverwendbar machen**
|
||||
|
||||
```bash
|
||||
|
||||
begruesse() { echo "Hallo $1!"
|
||||
|
||||
declare -A args=(
|
||||
|
||||
[name]="Welt"}Speichere deine Funktionen in einer separaten Datei, z. B. `funktionen.sh`, und **sourcen** sie in anderen Skripten:
|
||||
|
||||
[sprache]="de"
|
||||
|
||||
)```
|
||||
|
||||
|
||||
|
||||
for arg in "$@"; do**funktionen.sh**
|
||||
|
||||
[[ $arg == *=* ]] || continue
|
||||
|
||||
key="${arg%%=*}"**hauptskript.sh:**
|
||||
|
||||
val="${arg#*=}"
|
||||
|
||||
args[$key]="$val"```bash```bash
|
||||
|
||||
done
|
||||
|
||||
#!/bin/bash#!/bin/bash
|
||||
|
||||
echo "Hallo ${args[name]}! (Sprache: ${args[sprache]})"
|
||||
|
||||
}source ./funktionen.shbegruesse() {
|
||||
|
||||
|
||||
|
||||
begruesse name=Anna sprache=en echo "Hallo $1!"
|
||||
|
||||
```
|
||||
|
||||
begruesse "Welt"}
|
||||
|
||||
## Praktische Beispiele
|
||||
|
||||
``````
|
||||
|
||||
### Backup-Funktion
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
backup_datei() {Alternative: `. ./funktionen.sh`**hauptskript.sh**
|
||||
|
||||
local datei="$1"
|
||||
|
||||
local backup="${datei}.backup-$(date +%Y%m%d)"
|
||||
|
||||
|
||||
|
||||
if [[ -f "$datei" ]]; then## Lokale Variablen```bash
|
||||
|
||||
cp "$datei" "$backup"
|
||||
|
||||
echo "Backup erstellt: $backup"#!/bin/bash
|
||||
|
||||
else
|
||||
|
||||
echo "Fehler: $datei nicht gefunden" >&2Verwende `local`, um Variablen nur innerhalb der Funktion sichtbar zu machen:source ./funktionen.sh
|
||||
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
```bashbegruesse "Welt"
|
||||
|
||||
backup_datei wichtig.txt
|
||||
|
||||
```addiere() {```
|
||||
|
||||
|
||||
|
||||
### Fehlerbehandlung local summe=$(( $1 + $2 ))
|
||||
|
||||
|
||||
|
||||
```bash echo "$summe"Oder mit:
|
||||
|
||||
sicheres_loeschen() {
|
||||
|
||||
local datei="$1"}
|
||||
|
||||
|
||||
|
||||
if [[ ! -f "$datei" ]]; then``````bash
|
||||
|
||||
echo "Fehler: $datei existiert nicht" >&2
|
||||
|
||||
return 1. ./funktionen.sh
|
||||
|
||||
fi
|
||||
|
||||
## Default-Werte für Parameter```
|
||||
|
||||
read -p "Wirklich $datei löschen? (j/n) " antwort
|
||||
|
||||
if [[ "$antwort" == "j" ]]; then
|
||||
|
||||
rm "$datei"
|
||||
|
||||
echo "$datei gelöscht"```bash---
|
||||
|
||||
else
|
||||
|
||||
echo "Abgebrochen"mein_script() {
|
||||
|
||||
fi
|
||||
|
||||
} local name="${1:-Welt}" # Standardwert 'Welt'### 🔹 **Bonus: Funktionen mit lokaler Variable**
|
||||
|
||||
```
|
||||
|
||||
local sprache="${2:-de}" # Standardwert 'de'
|
||||
|
||||
### Mehrere Rückgabewerte
|
||||
|
||||
Verwende `local`, um Variablen nur innerhalb der Funktion sichtbar zu machen:
|
||||
|
||||
```bash
|
||||
|
||||
datei_info() { echo "Name: $name, Sprache: $sprache"
|
||||
|
||||
local datei="$1"
|
||||
|
||||
}```bash
|
||||
|
||||
if [[ -f "$datei" ]]; then
|
||||
|
||||
echo "$(wc -l < "$datei")" # Zeilenaddiere() {
|
||||
|
||||
echo "$(wc -w < "$datei")" # Wörter
|
||||
|
||||
echo "$(stat -c%s "$datei")" # Größemein_script "Anna" "en" # Name: Anna, Sprache: en local summe=$(( $1 + $2 ))
|
||||
|
||||
fi
|
||||
|
||||
}mein_script "Bob" # Name: Bob, Sprache: de echo "$summe"
|
||||
|
||||
|
||||
|
||||
# Verwendung```}
|
||||
|
||||
read zeilen woerter groesse <<< $(datei_info text.txt)
|
||||
|
||||
echo "Zeilen: $zeilen, Wörter: $woerter, Größe: $groesse"```
|
||||
|
||||
```
|
||||
|
||||
## Benannte Argumente simulieren
|
||||
|
||||
## Best Practices
|
||||
|
||||
---
|
||||
|
||||
### Eingabevalidierung
|
||||
|
||||
### Mit case und Schleife
|
||||
|
||||
```bash
|
||||
|
||||
verarbeite_zahl() {## 🧩 Beispiel 1: Named Arguments via `local` + Parameter Expansion
|
||||
|
||||
local zahl="$1"
|
||||
|
||||
```bash
|
||||
|
||||
if ! [[ "$zahl" =~ ^[0-9]+$ ]]; then
|
||||
|
||||
echo "Fehler: Keine gültige Zahl" >&2begruesse() {```bash
|
||||
|
||||
return 1
|
||||
|
||||
fi local name="Welt"mein_script() {
|
||||
|
||||
|
||||
|
||||
echo "Ergebnis: $((zahl * 2))" local sprache="de" local name="${1:-Welt}" # Standardwert 'Welt'
|
||||
|
||||
}
|
||||
|
||||
``` local sprache="${2:-de}" # Standardwert 'de'
|
||||
|
||||
|
||||
|
||||
### Dokumentation for arg in "$@"; do
|
||||
|
||||
|
||||
|
||||
```bash case $arg in echo "Name: $name"
|
||||
|
||||
# Berechnet die Summe zweier Zahlen
|
||||
|
||||
# Parameter: --name=*) echo "Sprache: $sprache"
|
||||
|
||||
# $1 - erste Zahl
|
||||
|
||||
# $2 - zweite Zahl name="${arg#*=}"}
|
||||
|
||||
# Rückgabe:
|
||||
|
||||
# Summe der beiden Zahlen ;;
|
||||
|
||||
addiere() {
|
||||
|
||||
echo $(( $1 + $2 )) --sprache=*|--lang=*)mein_script "Anna" "en"
|
||||
|
||||
}
|
||||
|
||||
``` sprache="${arg#*=}"mein_script "Bob"
|
||||
|
||||
|
||||
|
||||
### Fehler propagieren ;;```
|
||||
|
||||
|
||||
|
||||
```bash *)
|
||||
|
||||
hauptfunktion() {
|
||||
|
||||
hilfsfunktion || return $? echo "Unbekannte Option: $arg" >&2➡️ Ausgabe:
|
||||
|
||||
# Weiterer Code nur wenn hilfsfunktion erfolgreich
|
||||
|
||||
} ;;
|
||||
|
||||
```
|
||||
|
||||
esac```
|
||||
|
||||
## Siehe auch
|
||||
|
||||
doneName: Anna
|
||||
|
||||
- [[grep]] - Textsuche in Scripten
|
||||
|
||||
- [[sed]] - Textmanipulation in FunktionenSprache: en
|
||||
|
||||
- [[find]] - Dateien in Funktionen verarbeiten
|
||||
|
||||
echo "Hallo $name! (Sprache: $sprache)"Name: Bob
|
||||
|
||||
}Sprache: de
|
||||
|
||||
```
|
||||
|
||||
begruesse --name=Anna --sprache=en
|
||||
|
||||
```Aber das sind **positionsbasierte Argumente**, keine echten "benannten".
|
||||
|
||||
|
||||
|
||||
**Vorteile:**---
|
||||
|
||||
- Reihenfolge der Argumente ist egal
|
||||
|
||||
- Default-Werte bleiben bestehen## 🧩 Beispiel 2: Simulierte **benannte Argumente** mit `case` oder Schleife
|
||||
|
||||
- Sehr gut lesbar
|
||||
|
||||
Du kannst Argumente wie `--name=Anna` oder `--lang=en` verwenden:
|
||||
|
||||
### Mit assoziativem Array
|
||||
|
||||
```bash
|
||||
|
||||
```bashbegruesse() {
|
||||
|
||||
begruesse() { local name="Welt"
|
||||
|
||||
declare -A args=( local sprache="de"
|
||||
|
||||
[name]="Welt"
|
||||
|
||||
[sprache]="de" for arg in "$@"; do
|
||||
|
||||
) case $arg in
|
||||
|
||||
--name=*)
|
||||
|
||||
for arg in "$@"; do name="${arg#*=}"
|
||||
|
||||
[[ $arg == *=* ]] || continue ;;
|
||||
|
||||
key="${arg%%=*}" --sprache=*|--lang=*)
|
||||
|
||||
val="${arg#*=}" sprache="${arg#*=}"
|
||||
|
||||
args[$key]="$val" ;;
|
||||
|
||||
done *)
|
||||
|
||||
echo "Unbekannte Option: $arg" >&2
|
||||
|
||||
echo "Hallo ${args[name]}! (Sprache: ${args[sprache]})" ;;
|
||||
|
||||
} esac
|
||||
|
||||
done
|
||||
|
||||
begruesse name=Anna sprache=en
|
||||
|
||||
``` echo "Hallo $name! (Sprache: $sprache)"
|
||||
|
||||
}
|
||||
|
||||
## Siehe auch
|
||||
|
||||
begruesse --name=Anna --sprache=en
|
||||
|
||||
- [[find]] - BASH-Befehl zum Suchen von Dateienbegruesse
|
||||
|
||||
- [[grep]] - Textsuche in Dateien```
|
||||
|
||||
|
||||
➡️ Ausgabe:
|
||||
|
||||
```
|
||||
Hallo Anna! (Sprache: en)
|
||||
Hallo Welt! (Sprache: de)
|
||||
```
|
||||
|
||||
✅ Vorteil: Reihenfolge der Argumente ist egal
|
||||
✅ Default-Werte bleiben bestehen
|
||||
✅ Sehr gut lesbar
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Beispiel 3: Named Args via **`declare -A` (assoziatives Array)**
|
||||
|
||||
Etwas fortgeschrittener, aber elegant:
|
||||
|
||||
```bash
|
||||
begruesse() {
|
||||
declare -A args=(
|
||||
[name]="Welt"
|
||||
[sprache]="de"
|
||||
)
|
||||
|
||||
for arg in "$@"; do
|
||||
[[ $arg == *=* ]] || continue
|
||||
key="${arg%%=*}"
|
||||
val="${arg#*=}"
|
||||
args[$key]="$val"
|
||||
done
|
||||
|
||||
echo "Hallo ${args[name]}! (Sprache: ${args[sprache]})"
|
||||
}
|
||||
|
||||
begruesse name=Anna sprache=en
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Beispiel 4: Default-Werte per `:`-Operator
|
||||
|
||||
Falls du Parameter ohne Parsing willst, kannst du Default-Werte einfach so setzen:
|
||||
|
||||
```bash
|
||||
begruesse() {
|
||||
local name="${1:-Welt}"
|
||||
local sprache="${2:-de}"
|
||||
|
||||
echo "Hallo $name in Sprache $sprache"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔹 Empfehlung
|
||||
|
||||
Wenn du Funktionen **häufig wiederverwenden** oder **CLI-ähnliche Aufrufe** unterstützen willst, ist **Variante 2 (mit `--option=wert`)** am besten:
|
||||
|
||||
- Lesbar
|
||||
|
||||
- Robust
|
||||
|
||||
- Einfach erweiterbar
|
||||
|
||||
|
||||
---
|
||||
@@ -0,0 +1,365 @@
|
||||
# Dateiberechtigungen - chmod und chown
|
||||
|
||||
Verwaltung von Zugriffsrechten, Eigentümern und Gruppen in Linux.
|
||||
|
||||
## Rechte-System in Linux
|
||||
|
||||
Jede Datei hat:
|
||||
- **Eigentümer (Owner)** - der Benutzer, dem die Datei gehört
|
||||
- **Gruppe (Group)** - eine Benutzergruppe
|
||||
- **Zugriffsrechte** für drei Bereiche:
|
||||
- **u** (user) = Eigentümer
|
||||
- **g** (group) = Gruppe
|
||||
- **o** (others) = Andere
|
||||
|
||||
Jeder Bereich hat drei Rechte:
|
||||
- **r** (read) = Lesen (4)
|
||||
- **w** (write) = Schreiben (2)
|
||||
- **x** (execute) = Ausführen (1)
|
||||
|
||||
## Rechte anzeigen
|
||||
|
||||
```bash
|
||||
ls -l datei.txt
|
||||
```
|
||||
|
||||
Ausgabe:
|
||||
```
|
||||
-rw-r--r-- 1 alice developers 1234 Nov 7 10:00 datei.txt
|
||||
```
|
||||
|
||||
- Position 1: Dateityp (`-` = Datei, `d` = Verzeichnis, `l` = Link)
|
||||
- Position 2-4: User-Rechte (`rw-`)
|
||||
- Position 5-7: Group-Rechte (`r--`)
|
||||
- Position 8-10: Other-Rechte (`r--`)
|
||||
- `alice` = Eigentümer
|
||||
- `developers` = Gruppe
|
||||
|
||||
## chmod - Zugriffsrechte ändern
|
||||
|
||||
### Symbolische Notation
|
||||
|
||||
```bash
|
||||
chmod [ugoa][+-=][rwx] datei
|
||||
```
|
||||
|
||||
**Rechte hinzufügen:**
|
||||
```bash
|
||||
chmod u+x script.sh # Eigentümer: ausführbar
|
||||
chmod g+w datei.txt # Gruppe: schreibbar
|
||||
chmod o+r datei.txt # Andere: lesbar
|
||||
chmod a+x script.sh # Alle: ausführbar
|
||||
```
|
||||
|
||||
**Rechte entfernen:**
|
||||
```bash
|
||||
chmod u-x script.sh # Eigentümer: nicht ausführbar
|
||||
chmod g-w datei.txt # Gruppe: nicht schreibbar
|
||||
chmod o-r datei.txt # Andere: nicht lesbar
|
||||
```
|
||||
|
||||
**Rechte setzen (überschreiben):**
|
||||
```bash
|
||||
chmod u=rw,g=r,o= datei.txt # User: rw, Group: r, Others: keine
|
||||
chmod a=r datei.txt # Alle: nur lesen
|
||||
```
|
||||
|
||||
### Numerische Notation (Oktal)
|
||||
|
||||
Rechte als dreistellige Oktalzahl:
|
||||
|
||||
| Wert | Rechte | Bedeutung |
|
||||
|------|--------|-----------|
|
||||
| 0 | `---` | Keine Rechte |
|
||||
| 1 | `--x` | Ausführen |
|
||||
| 2 | `-w-` | Schreiben |
|
||||
| 3 | `-wx` | Schreiben + Ausführen |
|
||||
| 4 | `r--` | Lesen |
|
||||
| 5 | `r-x` | Lesen + Ausführen |
|
||||
| 6 | `rw-` | Lesen + Schreiben |
|
||||
| 7 | `rwx` | Alle Rechte |
|
||||
|
||||
**Häufige Kombinationen:**
|
||||
```bash
|
||||
chmod 644 datei.txt # rw-r--r-- (Standard für Dateien)
|
||||
chmod 755 script.sh # rwxr-xr-x (Standard für Scripts)
|
||||
chmod 700 privat.key # rwx------ (Nur Eigentümer)
|
||||
chmod 600 ~/.ssh/id_rsa # rw------- (SSH-Schlüssel)
|
||||
chmod 777 verzeichnis # rwxrwxrwx (Alle Rechte - UNSICHER!)
|
||||
```
|
||||
|
||||
Beispiel: `chmod 755` bedeutet:
|
||||
- User: 7 (rwx)
|
||||
- Group: 5 (r-x)
|
||||
- Others: 5 (r-x)
|
||||
|
||||
### Rekursiv
|
||||
|
||||
```bash
|
||||
chmod -R 755 /pfad/zum/verzeichnis
|
||||
```
|
||||
|
||||
**Nur Verzeichnisse oder nur Dateien:**
|
||||
```bash
|
||||
find . -type d -exec chmod 755 {} + # Alle Verzeichnisse
|
||||
find . -type f -exec chmod 644 {} + # Alle Dateien
|
||||
```
|
||||
|
||||
### Spezielle Rechte
|
||||
|
||||
**Sticky Bit** (nur Eigentümer kann löschen):
|
||||
```bash
|
||||
chmod +t /tmp # Symbolic
|
||||
chmod 1777 verzeichnis # Numeric (rwxrwxrwt)
|
||||
```
|
||||
|
||||
**SUID** (läuft mit Rechten des Eigentümers):
|
||||
```bash
|
||||
chmod u+s /usr/bin/passwd # Symbolic
|
||||
chmod 4755 datei # Numeric (rwsr-xr-x)
|
||||
```
|
||||
|
||||
**SGID** (neue Dateien erben Gruppe):
|
||||
```bash
|
||||
chmod g+s verzeichnis # Symbolic
|
||||
chmod 2755 verzeichnis # Numeric (rwxr-sr-x)
|
||||
```
|
||||
|
||||
### Praktische Beispiele
|
||||
|
||||
**Script ausführbar machen:**
|
||||
```bash
|
||||
chmod +x meinscript.sh
|
||||
./meinscript.sh
|
||||
```
|
||||
|
||||
**SSH-Verzeichnis absichern:**
|
||||
```bash
|
||||
chmod 700 ~/.ssh
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
chmod 644 ~/.ssh/id_rsa.pub
|
||||
chmod 600 ~/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
**Web-Verzeichnis:**
|
||||
```bash
|
||||
chmod -R 755 /var/www/html
|
||||
find /var/www/html -type f -exec chmod 644 {} +
|
||||
find /var/www/html -type d -exec chmod 755 {} +
|
||||
```
|
||||
|
||||
**Projekt-Verzeichnis:**
|
||||
```bash
|
||||
chmod -R u+rwX,g+rX,o-rwx projektordner
|
||||
```
|
||||
|
||||
(`X` = ausführbar nur für Verzeichnisse)
|
||||
|
||||
## chown - Eigentümer und Gruppe ändern
|
||||
|
||||
### Grundsyntax
|
||||
|
||||
```bash
|
||||
chown [OPTIONEN] EIGENTÜMER[:GRUPPE] DATEI
|
||||
```
|
||||
|
||||
### Eigentümer ändern
|
||||
|
||||
```bash
|
||||
chown alice datei.txt
|
||||
```
|
||||
|
||||
### Eigentümer und Gruppe ändern
|
||||
|
||||
```bash
|
||||
chown alice:developers datei.txt
|
||||
```
|
||||
|
||||
### Nur Gruppe ändern
|
||||
|
||||
```bash
|
||||
chown :developers datei.txt
|
||||
```
|
||||
|
||||
Oder mit `chgrp`:
|
||||
```bash
|
||||
chgrp developers datei.txt
|
||||
```
|
||||
|
||||
### Rekursiv
|
||||
|
||||
```bash
|
||||
chown -R alice:developers /pfad/zum/verzeichnis
|
||||
```
|
||||
|
||||
### Von anderem Benutzer übernehmen
|
||||
|
||||
```bash
|
||||
chown --reference=referenzdatei zieldatei
|
||||
```
|
||||
|
||||
### Praktische Beispiele
|
||||
|
||||
**Web-Server Verzeichnis:**
|
||||
```bash
|
||||
sudo chown -R www-data:www-data /var/www/html
|
||||
```
|
||||
|
||||
**Home-Verzeichnis korrigieren:**
|
||||
```bash
|
||||
sudo chown -R alice:alice /home/alice
|
||||
```
|
||||
|
||||
**Nach Copy von Root:**
|
||||
```bash
|
||||
sudo cp /root/datei.txt /home/alice/
|
||||
sudo chown alice:alice /home/alice/datei.txt
|
||||
```
|
||||
|
||||
**Nur Dateien, nicht Verzeichnisse:**
|
||||
```bash
|
||||
find /pfad -type f -exec chown alice:developers {} +
|
||||
```
|
||||
|
||||
**Nur bei Bedarf ändern:**
|
||||
```bash
|
||||
find /pfad ! -user alice -exec chown alice {} +
|
||||
find /pfad ! -group developers -exec chgrp developers {} +
|
||||
```
|
||||
|
||||
### Symbolische Links
|
||||
|
||||
Standardmäßig ändert `chown` das Ziel des Links:
|
||||
|
||||
```bash
|
||||
chown alice symlink # ändert Ziel
|
||||
chown -h alice symlink # ändert nur den Link selbst
|
||||
```
|
||||
|
||||
## Kombinierte Anwendung
|
||||
|
||||
### Berechtigungen komplett setzen
|
||||
|
||||
```bash
|
||||
sudo chown -R www-data:www-data /var/www/html
|
||||
sudo find /var/www/html -type d -exec chmod 755 {} +
|
||||
sudo find /var/www/html -type f -exec chmod 644 {} +
|
||||
```
|
||||
|
||||
### Projekt-Setup
|
||||
|
||||
```bash
|
||||
sudo chown -R alice:developers /opt/projekt
|
||||
chmod -R u+rwX,g+rwX,o-rwx /opt/projekt
|
||||
```
|
||||
|
||||
### Backup wiederherstellen
|
||||
|
||||
```bash
|
||||
sudo tar -xpf backup.tar.gz # -p bewahrt Rechte
|
||||
sudo chown -R alice:alice /home/alice/restored/
|
||||
```
|
||||
|
||||
## Berechtigungen prüfen
|
||||
|
||||
```bash
|
||||
ls -l datei.txt # Einfache Ansicht
|
||||
stat datei.txt # Detaillierte Info
|
||||
getfacl datei.txt # ACLs anzeigen (falls gesetzt)
|
||||
```
|
||||
|
||||
## Eigentümer-ID statt Name
|
||||
|
||||
```bash
|
||||
chown 1000:1000 datei.txt # Verwendet UID und GID direkt
|
||||
```
|
||||
|
||||
UIDs anzeigen:
|
||||
```bash
|
||||
id alice # UID und GIDs von alice
|
||||
```
|
||||
|
||||
## Fehler vermeiden
|
||||
|
||||
### Rekursive Änderungen testen
|
||||
|
||||
```bash
|
||||
# Erst anzeigen
|
||||
find /pfad -ls
|
||||
|
||||
# Dann ändern
|
||||
sudo chown -R alice:developers /pfad
|
||||
```
|
||||
|
||||
### NIEMALS auf Root-Verzeichnis
|
||||
|
||||
```bash
|
||||
# GEFÄHRLICH - bricht System
|
||||
sudo chown -R user:user / # NIEMALS!
|
||||
sudo chmod -R 777 / # NIEMALS!
|
||||
|
||||
# Nur eigene Verzeichnisse
|
||||
sudo chown -R user:user /home/user
|
||||
```
|
||||
|
||||
### Zu permissive Rechte
|
||||
|
||||
```bash
|
||||
# FALSCH - macht alles ausführbar
|
||||
chmod -R 777 verzeichnis # NICHT verwenden!
|
||||
|
||||
# RICHTIG - differenziert
|
||||
find verzeichnis -type d -exec chmod 755 {} +
|
||||
find verzeichnis -type f -exec chmod 644 {} +
|
||||
```
|
||||
|
||||
### Systemdateien
|
||||
|
||||
```bash
|
||||
# Wichtige Systemdateien sollten root gehören
|
||||
ls -l /etc/passwd /etc/shadow
|
||||
# -rw-r--r-- 1 root root ... /etc/passwd
|
||||
# -rw-r----- 1 root shadow ... /etc/shadow
|
||||
```
|
||||
|
||||
## Mit sudo
|
||||
|
||||
`chown` erfordert meist Root-Rechte:
|
||||
|
||||
```bash
|
||||
sudo chown root:root /etc/wichtig.conf
|
||||
sudo chmod 644 /etc/wichtig.conf
|
||||
```
|
||||
|
||||
Ohne sudo:
|
||||
```bash
|
||||
# Nur eigene Dateien
|
||||
chmod 644 meine_datei.txt
|
||||
|
||||
# chown nur als root
|
||||
chown alice datei.txt # Permission denied (außer eigene Datei)
|
||||
```
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
| Befehl | Zweck | Beispiel |
|
||||
|--------|-------|----------|
|
||||
| `chmod` | Rechte ändern | `chmod 755 script.sh` |
|
||||
| `chown` | Eigentümer ändern | `chown alice:developers file` |
|
||||
| `chgrp` | Nur Gruppe ändern | `chgrp developers file` |
|
||||
| `ls -l` | Rechte anzeigen | `ls -l file` |
|
||||
| `stat` | Details anzeigen | `stat file` |
|
||||
|
||||
**Standard-Rechte:**
|
||||
- Dateien: `644` (rw-r--r--)
|
||||
- Scripts: `755` (rwxr-xr-x)
|
||||
- Verzeichnisse: `755` (rwxr-xr-x)
|
||||
- Private Dateien: `600` (rw-------)
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[find]] - Dateien mit bestimmten Rechten/Eigentümern finden
|
||||
- [[ls]] - Rechte und Eigentümer anzeigen
|
||||
- [[Symlinks]] - Links bleiben bei chown erhalten
|
||||
- [[tar]] - Rechte in Archiven bewahren
|
||||
- [[rsync]] - Rechte bei Synchronisation
|
||||
@@ -0,0 +1,115 @@
|
||||
# Linux BASH: Permanente Verfügbarkeit von Dateien und Pfaden
|
||||
|
||||
Es gibt mehrere Methoden, um Dateien oder Pfade in Linux BASH permanent verfügbar zu machen:
|
||||
|
||||
## PATH-Variable erweitern
|
||||
|
||||
### Temporär (aktuelle Session)
|
||||
```bash
|
||||
export PATH="$PATH:/pfad/zum/verzeichnis"
|
||||
```
|
||||
|
||||
### Permanent für aktuellen Benutzer
|
||||
Füge folgende Zeile in `~/.bashrc` oder `~/.profile` ein:
|
||||
```bash
|
||||
export PATH="$PATH:/pfad/zum/verzeichnis"
|
||||
```
|
||||
|
||||
### Permanent systemweit
|
||||
Bearbeite `/etc/environment`:
|
||||
```bash
|
||||
sudo nano /etc/environment
|
||||
```
|
||||
Erweitere die PATH-Zeile:
|
||||
```
|
||||
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/dein/pfad"
|
||||
```
|
||||
|
||||
## Symbolische Links erstellen
|
||||
|
||||
### Link in systemweitem Bin-Verzeichnis
|
||||
```bash
|
||||
sudo ln -s /vollständiger/pfad/zur/datei /usr/local/bin/dateiname
|
||||
```
|
||||
|
||||
### Link in persönlichem Bin-Verzeichnis
|
||||
```bash
|
||||
mkdir -p ~/bin
|
||||
ln -s /vollständiger/pfad/zur/datei ~/bin/dateiname
|
||||
# ~/bin zu PATH hinzufügen falls nicht vorhanden
|
||||
echo 'export PATH="$PATH:$HOME/bin"' >> ~/.bashrc
|
||||
```
|
||||
|
||||
## Aliase verwenden
|
||||
|
||||
### In ~/.bashrc hinzufügen
|
||||
```bash
|
||||
alias meinprogramm='/vollständiger/pfad/zur/datei'
|
||||
alias cdprojekt='cd /pfad/zum/projekt'
|
||||
```
|
||||
|
||||
## Umgebungsvariablen für Pfade
|
||||
|
||||
### In ~/.bashrc definieren
|
||||
```bash
|
||||
export MEIN_PROJEKT_PFAD="/pfad/zum/projekt"
|
||||
export MEIN_SCRIPT_PFAD="/pfad/zu/scripts"
|
||||
```
|
||||
|
||||
Verwendung:
|
||||
```bash
|
||||
cd $MEIN_PROJEKT_PFAD
|
||||
$MEIN_SCRIPT_PFAD/meinscript.sh
|
||||
```
|
||||
|
||||
## Anwendung der Änderungen
|
||||
|
||||
Nach Bearbeitung der Konfigurationsdateien:
|
||||
```bash
|
||||
source ~/.bashrc
|
||||
# oder
|
||||
exec bash
|
||||
# oder Terminal neu starten
|
||||
```
|
||||
|
||||
## Praxisbeispiele
|
||||
|
||||
### Eigene Scripts verfügbar machen
|
||||
```bash
|
||||
# 1. Persönliches Scripts-Verzeichnis erstellen
|
||||
mkdir -p ~/scripts
|
||||
|
||||
# 2. Script dort ablegen
|
||||
cp meinscript.sh ~/scripts/
|
||||
|
||||
# 3. Ausführbar machen
|
||||
chmod +x ~/scripts/meinscript.sh
|
||||
|
||||
# 4. PATH erweitern in ~/.bashrc
|
||||
echo 'export PATH="$PATH:$HOME/scripts"' >> ~/.bashrc
|
||||
|
||||
# 5. Änderungen laden
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
### Häufig verwendete Verzeichnisse
|
||||
```bash
|
||||
# In ~/.bashrc
|
||||
alias proj='cd /home/user/projekte'
|
||||
alias docs='cd /home/user/dokumente'
|
||||
export WORKSPACE="/home/user/workspace"
|
||||
```
|
||||
|
||||
## Wichtige Hinweise
|
||||
|
||||
- **Reihenfolge im PATH**: Erste Treffer werden verwendet
|
||||
- **Sicherheit**: Keine unsicheren Verzeichnisse in PATH aufnehmen
|
||||
- **Systemweite vs. Benutzer-spezifische** Änderungen beachten
|
||||
- **Backup**: Konfigurationsdateien vor Änderungen sichern
|
||||
|
||||
---
|
||||
|
||||
**Verwandte Themen:**
|
||||
- [[Linux Shell Konfiguration]]
|
||||
- [[BASH Umgebungsvariablen]]
|
||||
- [[Linux Dateisystem Navigation]]
|
||||
@@ -0,0 +1,107 @@
|
||||
# Symbolische Links (Symlinks)
|
||||
|
||||
Ein symbolischer Link (Symlink) ist eine spezielle Datei, die auf eine andere Datei oder ein Verzeichnis verweist.
|
||||
|
||||
## Symlink erstellen
|
||||
|
||||
```bash
|
||||
ln -s /pfad/zum/ziel /pfad/zum/link
|
||||
```
|
||||
|
||||
Optionen:
|
||||
- `-s` → Symlink erstellen (statt Hardlink)
|
||||
- `-f` → vorhandenen Link überschreiben
|
||||
- `-n` → falls Link auf Verzeichnis verweist, Link selbst überschreiben
|
||||
|
||||
Beispiel:
|
||||
|
||||
```bash
|
||||
ln -s /opt/programm/binary /usr/local/bin/programm
|
||||
```
|
||||
|
||||
## Ziel eines Symlinks anzeigen
|
||||
|
||||
```bash
|
||||
readlink meinlink
|
||||
```
|
||||
|
||||
Mit absolutem Pfad (löst verschachtelte Links auf):
|
||||
|
||||
```bash
|
||||
readlink -f meinlink
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
|
||||
```bash
|
||||
$ readlink mysoftlink
|
||||
../zielordner/datei.txt
|
||||
|
||||
$ readlink -f mysoftlink
|
||||
/home/user/zielordner/datei.txt
|
||||
```
|
||||
|
||||
## Symlink aktualisieren
|
||||
|
||||
Einen Symlink kann man nicht direkt ändern, sondern muss ihn neu erstellen:
|
||||
|
||||
```bash
|
||||
ln -sfn /neues/ziel meinlink
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
link="meinlink"
|
||||
|
||||
# Aktuelles Ziel auslesen
|
||||
altes_ziel=$(readlink "$link")
|
||||
echo "Aktuelles Ziel: $altes_ziel"
|
||||
|
||||
# Neues Ziel setzen
|
||||
neues_ziel="/pfad/zum/neuen/ziel"
|
||||
ln -sfn "$neues_ziel" "$link"
|
||||
|
||||
echo "Neues Ziel: $(readlink $link)"
|
||||
```
|
||||
|
||||
## Symlinks vs. Hardlinks
|
||||
|
||||
**Symlinks:**
|
||||
- Verweisen auf Pfad (nicht auf Inode)
|
||||
- Können auf Dateien und Verzeichnisse verweisen
|
||||
- Funktionieren über Dateisystemgrenzen hinweg
|
||||
- Brechen, wenn Ziel gelöscht wird
|
||||
|
||||
**Hardlinks:**
|
||||
- Verweisen direkt auf Inode
|
||||
- Nur für Dateien (nicht für Verzeichnisse)
|
||||
- Müssen im gleichen Dateisystem liegen
|
||||
- Bleiben gültig, auch wenn Originaldatei gelöscht wird
|
||||
|
||||
## Desktop-Verknüpfungen erstellen
|
||||
|
||||
Für Desktop-Umgebungen (GNOME, KDE, XFCE) verwendet man `.desktop`-Dateien:
|
||||
|
||||
**weblink.desktop:**
|
||||
```ini
|
||||
[Desktop Entry]
|
||||
Name=Open ChatGPT
|
||||
Type=Link
|
||||
URL=https://chat.openai.com/
|
||||
Icon=web-browser
|
||||
```
|
||||
|
||||
Ausführbar machen:
|
||||
|
||||
```bash
|
||||
chmod +x weblink.desktop
|
||||
```
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[find]] - Dateien suchen (z.B. nach Symlinks mit `-type l`)
|
||||
- [[ls]] - Symlinks in Verzeichnissen anzeigen
|
||||
- [[Dateiberechtigungen]] - Rechte von Links und Zielen
|
||||
- [[lsblk]] - Block-Geräte anzeigen
|
||||
@@ -0,0 +1,257 @@
|
||||
# awk - Textverarbeitung und Datenextraktion
|
||||
|
||||
`awk` ist eine mächtige Programmiersprache für Textverarbeitung, besonders nützlich für spaltenbasierte Daten.
|
||||
|
||||
## Grundsyntax
|
||||
|
||||
```bash
|
||||
awk 'MUSTER { AKTION }' datei.txt
|
||||
```
|
||||
|
||||
## Spalten ausgeben
|
||||
|
||||
### Einzelne Spalten
|
||||
|
||||
```bash
|
||||
awk '{print $1}' datei.txt # Erste Spalte
|
||||
awk '{print $2}' datei.txt # Zweite Spalte
|
||||
awk '{print $NF}' datei.txt # Letzte Spalte
|
||||
```
|
||||
|
||||
`$0` = ganze Zeile, `$1` = erste Spalte, `$2` = zweite, etc.
|
||||
|
||||
### Mehrere Spalten
|
||||
|
||||
```bash
|
||||
awk '{print $1, $3}' datei.txt
|
||||
awk '{print $1 " - " $3}' datei.txt
|
||||
```
|
||||
|
||||
## Trennzeichen (Delimiter)
|
||||
|
||||
### Standard (Leerzeichen/Tab)
|
||||
|
||||
```bash
|
||||
awk '{print $1}' datei.txt
|
||||
```
|
||||
|
||||
### Eigenes Trennzeichen
|
||||
|
||||
```bash
|
||||
awk -F: '{print $1}' /etc/passwd # Doppelpunkt
|
||||
awk -F, '{print $1, $3}' datei.csv # Komma
|
||||
awk -F'|' '{print $2}' datei.txt # Pipe
|
||||
```
|
||||
|
||||
### Mehrere Trennzeichen
|
||||
|
||||
```bash
|
||||
awk -F'[,:]' '{print $1}' datei.txt
|
||||
```
|
||||
|
||||
## Muster (Pattern)
|
||||
|
||||
### Zeilen mit bestimmtem Text
|
||||
|
||||
```bash
|
||||
awk '/ERROR/ {print}' logfile.txt
|
||||
awk '/ERROR/' logfile.txt # Kurzform
|
||||
```
|
||||
|
||||
### Reguläre Ausdrücke
|
||||
|
||||
```bash
|
||||
awk '/^[0-9]/ {print}' datei.txt # Zeilen mit Zahl am Anfang
|
||||
awk '/ERROR|WARNING/' logfile.txt # ERROR oder WARNING
|
||||
```
|
||||
|
||||
### Spaltenbasierte Bedingungen
|
||||
|
||||
```bash
|
||||
awk '$3 > 100 {print}' datei.txt # 3. Spalte > 100
|
||||
awk '$1 == "root" {print}' /etc/passwd # 1. Spalte = "root"
|
||||
awk '$2 != "active" {print}' status.txt # 2. Spalte ≠ "active"
|
||||
```
|
||||
|
||||
### Mehrere Bedingungen
|
||||
|
||||
```bash
|
||||
awk '$3 > 100 && $4 < 200 {print}' datei.txt
|
||||
awk '$1 == "Alice" || $1 == "Bob" {print}' datei.txt
|
||||
```
|
||||
|
||||
## Berechnungen
|
||||
|
||||
### Summe
|
||||
|
||||
```bash
|
||||
awk '{sum += $1} END {print sum}' zahlen.txt
|
||||
```
|
||||
|
||||
### Durchschnitt
|
||||
|
||||
```bash
|
||||
awk '{sum += $1; count++} END {print sum/count}' zahlen.txt
|
||||
```
|
||||
|
||||
### Maximum/Minimum
|
||||
|
||||
```bash
|
||||
awk 'BEGIN {max=0} {if($1>max) max=$1} END {print max}' zahlen.txt
|
||||
awk 'NR==1 {min=$1} {if($1<min) min=$1} END {print min}' zahlen.txt
|
||||
```
|
||||
|
||||
## Formatierte Ausgabe
|
||||
|
||||
### Mit printf
|
||||
|
||||
```bash
|
||||
awk '{printf "%s: %d\n", $1, $2}' datei.txt
|
||||
awk '{printf "%-10s %5d\n", $1, $2}' datei.txt # Formatiert
|
||||
```
|
||||
|
||||
### Spalten ausrichten
|
||||
|
||||
```bash
|
||||
awk '{printf "%-15s %10s\n", $1, $2}' datei.txt
|
||||
```
|
||||
|
||||
## Eingebaute Variablen
|
||||
|
||||
```bash
|
||||
awk '{print NR, $0}' datei.txt # NR = Zeilennummer
|
||||
awk '{print NF, $0}' datei.txt # NF = Anzahl Felder
|
||||
awk 'NR==5 {print}' datei.txt # Nur Zeile 5
|
||||
awk 'NR>=10 && NR<=20' datei.txt # Zeilen 10-20
|
||||
```
|
||||
|
||||
Wichtige Variablen:
|
||||
- `NR` = Nummer der aktuellen Zeile
|
||||
- `NF` = Anzahl der Felder
|
||||
- `FS` = Field Separator (Eingabe)
|
||||
- `OFS` = Output Field Separator (Ausgabe)
|
||||
|
||||
## BEGIN und END
|
||||
|
||||
```bash
|
||||
awk 'BEGIN {print "Start"} {print} END {print "Ende"}' datei.txt
|
||||
```
|
||||
|
||||
```bash
|
||||
awk 'BEGIN {FS=":"; OFS="\t"} {print $1, $3}' /etc/passwd
|
||||
```
|
||||
|
||||
## Praktische Beispiele
|
||||
|
||||
### /etc/passwd auswerten
|
||||
|
||||
```bash
|
||||
# Alle Benutzernamen
|
||||
awk -F: '{print $1}' /etc/passwd
|
||||
|
||||
# User mit UID >= 1000
|
||||
awk -F: '$3 >= 1000 {print $1}' /etc/passwd
|
||||
|
||||
# User und Shell
|
||||
awk -F: '{print $1 ": " $7}' /etc/passwd
|
||||
```
|
||||
|
||||
### Prozesse analysieren
|
||||
|
||||
```bash
|
||||
# Speichernutzung
|
||||
ps aux | awk '{sum += $6} END {print sum/1024 " MB"}'
|
||||
|
||||
# Top 5 Prozesse nach Speicher
|
||||
ps aux | awk '{print $6, $11}' | sort -rn | head -5
|
||||
```
|
||||
|
||||
### CSV-Dateien
|
||||
|
||||
```bash
|
||||
# Zweite Spalte summieren
|
||||
awk -F, '{sum += $2} END {print sum}' data.csv
|
||||
|
||||
# Filtern und ausgeben
|
||||
awk -F, '$3 > 1000 {print $1, $2}' sales.csv
|
||||
```
|
||||
|
||||
### Logfile-Analyse
|
||||
|
||||
```bash
|
||||
# Nur ERROR-Zeilen mit Zeitstempel
|
||||
awk '/ERROR/ {print $1, $2, $0}' app.log
|
||||
|
||||
# Fehler zählen
|
||||
awk '/ERROR/ {count++} END {print count}' app.log
|
||||
|
||||
# Nach Zeit filtern
|
||||
awk '$1 >= "2025-11-07" && $1 <= "2025-11-08"' log.txt
|
||||
```
|
||||
|
||||
### Apache/Nginx Logs
|
||||
|
||||
```bash
|
||||
# IP-Adressen extrahieren
|
||||
awk '{print $1}' access.log | sort | uniq -c | sort -rn
|
||||
|
||||
# Nur 404-Fehler
|
||||
awk '$9 == 404 {print $7}' access.log
|
||||
```
|
||||
|
||||
### Duplikate zählen
|
||||
|
||||
```bash
|
||||
awk '{count[$1]++} END {for(key in count) print key, count[key]}' datei.txt
|
||||
```
|
||||
|
||||
## Arrays
|
||||
|
||||
```bash
|
||||
awk '{arr[$1] += $2} END {for (key in arr) print key, arr[key]}' datei.txt
|
||||
```
|
||||
|
||||
## Mehrere Dateien
|
||||
|
||||
```bash
|
||||
awk '{print FILENAME, $0}' datei1.txt datei2.txt
|
||||
```
|
||||
|
||||
## Mit Pipes
|
||||
|
||||
```bash
|
||||
cat datei.txt | awk '{print $1}'
|
||||
ls -l | awk '{print $9, $5}'
|
||||
df -h | awk 'NR>1 {print $1, $5}'
|
||||
```
|
||||
|
||||
## Komplexes Beispiel
|
||||
|
||||
```bash
|
||||
# Benutzerdefinierte Funktion
|
||||
awk '
|
||||
function celsius(f) {
|
||||
return (f - 32) * 5/9
|
||||
}
|
||||
{
|
||||
printf "%s: %.2f°C\n", $1, celsius($2)
|
||||
}
|
||||
' temperatures.txt
|
||||
```
|
||||
|
||||
## Vergleich: awk vs. andere Tools
|
||||
|
||||
| Task | Tool |
|
||||
|------|------|
|
||||
| Spalten extrahieren | `awk '{print $2}'` oder `cut -f2` |
|
||||
| Suchen | `awk '/pattern/'` oder `grep pattern` |
|
||||
| Ersetzen | `sed 's/alt/neu/'` |
|
||||
| Rechnen | `awk '{sum+=$1}'` |
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[grep]] - Textsuche
|
||||
- [[sed]] - Stream-Editor
|
||||
- [[find]] - Dateien finden
|
||||
- [[BASH Funktionen]] - awk in Funktionen nutzen
|
||||
- [[ls]] - Ausgabe mit awk verarbeiten
|
||||
@@ -0,0 +1,362 @@
|
||||
# find - Dateien und Verzeichnisse suchen
|
||||
|
||||
Der Befehl `find` durchsucht Verzeichnisse rekursiv nach Dateien oder Ordnern anhand verschiedener Kriterien.
|
||||
|
||||
## Grundsyntax
|
||||
|
||||
```bash
|
||||
find [Pfad] [Suchkriterien] [Aktionen]
|
||||
```
|
||||
|
||||
## Suchkriterien
|
||||
|
||||
### Nach Namen suchen
|
||||
|
||||
```bash
|
||||
find . -name "datei.txt" # exakte Übereinstimmung
|
||||
find . -iname "datei.txt" # case-insensitive
|
||||
find . -name "*.log" # mit Wildcards
|
||||
```
|
||||
|
||||
### Nach Dateityp suchen
|
||||
|
||||
```bash
|
||||
find . -type f # nur Dateien
|
||||
find . -type d # nur Verzeichnisse
|
||||
find . -type l # symbolische Links
|
||||
```
|
||||
|
||||
### Nach Dateigröße suchen
|
||||
|
||||
```bash
|
||||
find . -size +10M # größer als 10 MB
|
||||
find . -size -100k # kleiner als 100 KB
|
||||
find . -size 0 # leere Dateien
|
||||
```
|
||||
|
||||
### Nach Berechtigungen suchen
|
||||
|
||||
```bash
|
||||
find . -perm 644 # Dateien mit Rechten 644
|
||||
find . -user alice # Dateien von User "alice"
|
||||
find . -group admins # Dateien von Gruppe "admins"
|
||||
```
|
||||
|
||||
### Suchtiefe begrenzen
|
||||
|
||||
```bash
|
||||
find . -maxdepth 1 -type f
|
||||
```
|
||||
|
||||
Nur im aktuellen Ordner, nicht in Unterordnern.
|
||||
|
||||
## Suche nach Datum und Zeit
|
||||
|
||||
### Zeitstempel-Typen
|
||||
|
||||
- **mtime** (modification time) = Inhalt geändert
|
||||
- **atime** (access time) = Datei gelesen
|
||||
- **ctime** (change time) = Metadaten geändert (chmod, chown)
|
||||
|
||||
### Relative Zeitangaben (Tage)
|
||||
|
||||
```bash
|
||||
find . -mtime -7 # in den letzten 7 Tagen geändert
|
||||
find . -mtime +30 # älter als 30 Tage
|
||||
find . -atime -1 # in den letzten 24 Stunden geöffnet
|
||||
find . -ctime -1 # Metadaten in letzten 24h geändert
|
||||
```
|
||||
|
||||
Dateien zwischen X und Y Tagen:
|
||||
|
||||
```bash
|
||||
find . -mtime +7 -mtime -30
|
||||
```
|
||||
|
||||
### Absolute Zeitangaben (Datum, GNU find)
|
||||
|
||||
```bash
|
||||
find . -newermt "2025-04-01" # mtime nach Datum
|
||||
find . -newerat "2025-04-01" # atime nach Datum
|
||||
find . -newerct "2025-04-01" # ctime nach Datum
|
||||
find . -newermt "2023-09-01" ! -newermt "2023-09-10" # zwischen zwei Daten
|
||||
```
|
||||
|
||||
**Hinweis:** `-newermt/at/ct` sind GNU-Erweiterungen (nicht auf BSD/macOS).
|
||||
|
||||
### Mit Referenzdatei
|
||||
|
||||
```bash
|
||||
touch -d "2025-04-01" /tmp/refdate
|
||||
find . -newer /tmp/refdate
|
||||
```
|
||||
|
||||
### Übersicht Zeitoptionen
|
||||
|
||||
| Option | Bedeutung |
|
||||
|--------|-----------|
|
||||
| `-mtime -7` | in den letzten 7 Tagen geändert |
|
||||
| `-mtime +30` | älter als 30 Tage |
|
||||
| `-atime -2` | in den letzten 2 Tagen geöffnet |
|
||||
| `-ctime -1` | Metadaten in letzten 24h geändert |
|
||||
| `-newermt "2023-09-01"` | mtime nach Datum (GNU) |
|
||||
| `-newerat "2023-09-01"` | atime nach Datum (GNU) |
|
||||
| `-newerct "2023-09-01"` | ctime nach Datum (GNU) |
|
||||
| `-newer datei.txt` | neuer als Referenzdatei |
|
||||
|
||||
## Bedingungen kombinieren
|
||||
|
||||
### UND-Verknüpfung (Standard)
|
||||
|
||||
```bash
|
||||
find . -type f -size +1M -mtime -7
|
||||
```
|
||||
|
||||
Dateien größer als 1 MB UND in den letzten 7 Tagen geändert.
|
||||
|
||||
### ODER-Verknüpfung
|
||||
|
||||
```bash
|
||||
find . -type f \( -name "*.jpg" -o -name "*.png" \)
|
||||
```
|
||||
|
||||
Alle `.jpg` ODER `.png` Dateien.
|
||||
|
||||
### Negation
|
||||
|
||||
```bash
|
||||
find . -type f ! -iname "*.mp3"
|
||||
```
|
||||
|
||||
Alle Dateien, die NICHT auf `.mp3` enden.
|
||||
|
||||
Mehrere Endungen ausschließen:
|
||||
|
||||
```bash
|
||||
find . -type f ! \( -iname "*.mp3" -o -iname "*.flac" \)
|
||||
```
|
||||
|
||||
## Aktionen auf gefundene Dateien
|
||||
|
||||
### Anzeigen
|
||||
|
||||
```bash
|
||||
find . -name "*.log" -print # Standard
|
||||
find . -name "*.log" -ls # mit Details
|
||||
```
|
||||
|
||||
### Dateien löschen
|
||||
|
||||
**Grundprinzip:** Immer erst testen, dann löschen!
|
||||
|
||||
```bash
|
||||
# 1. Testen
|
||||
find . -name "*.tmp" -print
|
||||
|
||||
# 2. Anzahl prüfen
|
||||
find . -name "*.tmp" | wc -l
|
||||
|
||||
# 3. Dry-run
|
||||
find . -name "*.tmp" -exec echo rm {} +
|
||||
|
||||
# 4. Löschen
|
||||
find . -name "*.tmp" -delete
|
||||
```
|
||||
|
||||
Alternative mit `-exec`:
|
||||
|
||||
```bash
|
||||
find . -name "*.tmp" -exec rm {} + # effizient (mehrere auf einmal)
|
||||
find . -name "*.tmp" -exec rm {} \; # einzeln
|
||||
find . -name "*.tmp" -exec rm -i {} \; # mit Rückfrage
|
||||
```
|
||||
|
||||
Mit xargs (sicher bei Leerzeichen):
|
||||
|
||||
```bash
|
||||
find . -name "*.tmp" -print0 | xargs -0 rm
|
||||
```
|
||||
|
||||
### Mit -exec Befehle ausführen
|
||||
|
||||
```bash
|
||||
find . -name "*.log" -exec rm {} + # Löschen
|
||||
find . -type f -name "*.sh" -exec chmod +x {} + # Ausführbar machen
|
||||
find /etc -type f -mtime -1 -exec cp {} /backup/ \; # Kopieren
|
||||
find . -type f -name "*.log" -mtime +7 -exec gzip {} + # Komprimieren
|
||||
```
|
||||
|
||||
- `{}` = Platzhalter für gefundene Datei
|
||||
- `\;` = Ende des Befehls (einzeln, langsamer)
|
||||
- `+` = mehrere Dateien gleichzeitig (effizienter)
|
||||
|
||||
### Komplexe Shell-Befehle
|
||||
|
||||
```bash
|
||||
find . -type f -name "*.jpg" -exec sh -c 'for f; do
|
||||
convert "$f" -resize 800x "${f%.jpg}_small.jpg"
|
||||
done' _ {} +
|
||||
```
|
||||
|
||||
## Pfad- und Namensfilter
|
||||
|
||||
### Mit -path (Glob-Muster)
|
||||
|
||||
```bash
|
||||
find ~/Musik -type f -path "*/zzz Verschiedene/AlbumArt_*"
|
||||
```
|
||||
|
||||
`-path` verwendet Shell-Wildcards (Globs), nicht reguläre Ausdrücke.
|
||||
|
||||
### Mit -regex (Reguläre Ausdrücke)
|
||||
|
||||
```bash
|
||||
find ~/Musik -type f -regextype posix-extended \
|
||||
-regex '.*/zzz Verschiedene/AlbumArt_.*'
|
||||
```
|
||||
|
||||
`-regex` matcht den gesamten Pfad, daher oft `.*` am Anfang nötig.
|
||||
|
||||
## Praktische Anwendungsfälle
|
||||
|
||||
### Alte Dateien löschen
|
||||
|
||||
```bash
|
||||
find /tmp -type f -mtime +7 -delete
|
||||
```
|
||||
|
||||
### Leere Dateien/Verzeichnisse finden
|
||||
|
||||
```bash
|
||||
find . -type f -empty # leere Dateien
|
||||
find . -type d -empty # leere Ordner
|
||||
```
|
||||
|
||||
### Dateien mit falschen Rechten
|
||||
|
||||
```bash
|
||||
find / -type f -perm -o+w # weltweit schreibbar
|
||||
```
|
||||
|
||||
### Große Dateien finden
|
||||
|
||||
```bash
|
||||
find /home -type f -size +100M
|
||||
find . -type f -exec du -h {} + | sort -rh | head -10 # Top 10 größte
|
||||
```
|
||||
|
||||
### Dateien nach Datum und Pfad
|
||||
|
||||
```bash
|
||||
find ~/Musik -type f \
|
||||
-newermt "2025-04-01" \
|
||||
-path "*/zzz Verschiedene/AlbumArt_*" \
|
||||
-print
|
||||
```
|
||||
|
||||
### Dateien sichern
|
||||
|
||||
```bash
|
||||
find /etc -type f -mtime -1 -exec cp {} /backup/ \;
|
||||
```
|
||||
|
||||
### Backup-Kandidaten mit Datum
|
||||
|
||||
```bash
|
||||
find /backups -type f -name "*.tar.gz" \
|
||||
-newermt "2023-08-01" ! -newermt "2023-08-31"
|
||||
```
|
||||
|
||||
### Logfile-Analyse
|
||||
|
||||
```bash
|
||||
find /var/log -type f -size +100M -newermt "2023-09-01"
|
||||
```
|
||||
|
||||
### Nur Dateien, nicht Verzeichnisse ändern
|
||||
|
||||
```bash
|
||||
find . -type f -exec chmod 644 {} +
|
||||
find . -type d -exec chmod 755 {} +
|
||||
```
|
||||
|
||||
## Best Practices und Fehler vermeiden
|
||||
|
||||
### Sicherheit beim Löschen
|
||||
|
||||
```bash
|
||||
# IMMER erst testen
|
||||
find . -name "*.tmp" -print
|
||||
find . -name "*.tmp" | wc -l
|
||||
find . -name "*.tmp" -exec echo rm {} +
|
||||
|
||||
# Dann löschen
|
||||
find . -name "*.tmp" -delete
|
||||
```
|
||||
|
||||
### Leerzeichen in Dateinamen
|
||||
|
||||
```bash
|
||||
# RICHTIG: -print0 und xargs -0
|
||||
find . -name "*.txt" -print0 | xargs -0 rm
|
||||
|
||||
# RICHTIG: -exec mit +
|
||||
find . -name "*.txt" -exec rm {} +
|
||||
|
||||
# FALSCH: Pipe ohne -print0
|
||||
find . -name "*.txt" | rm # funktioniert nicht!
|
||||
```
|
||||
|
||||
### Trailing Slash bei -path
|
||||
|
||||
```bash
|
||||
find . -path "*/ordner/*" # Dateien IN ordner/
|
||||
find . -path "*/ordner" # NUR ordner/ selbst
|
||||
```
|
||||
|
||||
### -delete Reihenfolge
|
||||
|
||||
```bash
|
||||
# RICHTIG: -type f VOR -delete
|
||||
find . -type f -name "*.tmp" -delete
|
||||
|
||||
# FALSCH: kann Verzeichnisse löschen
|
||||
find . -name "*.tmp" -delete
|
||||
```
|
||||
|
||||
### Zu viele Argumente
|
||||
|
||||
```bash
|
||||
# FALSCH: kann "Argument list too long" geben
|
||||
find . -name "*.txt" -exec rm {} \;
|
||||
|
||||
# RICHTIG: mit +
|
||||
find . -name "*.txt" -exec rm {} +
|
||||
|
||||
# RICHTIG: mit xargs
|
||||
find . -name "*.txt" -print0 | xargs -0 rm
|
||||
```
|
||||
|
||||
## Alternative Tools
|
||||
|
||||
- **fd** - moderner, schneller find-Ersatz mit besserer Syntax
|
||||
- **ripgrep (rg)** - für Textsuche in Dateien
|
||||
- **locate** - schnelle Dateinamensuche (nutzt Datenbank)
|
||||
|
||||
Beispiel mit fd:
|
||||
|
||||
```bash
|
||||
fd "*.log" # Einfacher als find
|
||||
fd -t f -s +100M # Dateien > 100MB
|
||||
fd -e jpg -x convert {} ... # Mit exec
|
||||
```
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[ls]] - Dateien auflisten
|
||||
- [[grep]] - Textsuche in gefundenen Dateien
|
||||
- [[Dateiberechtigungen]] - Rechte und Eigentümer von Dateien
|
||||
- [[tar]] - Gefundene Dateien archivieren
|
||||
- [[rsync]] - Dateien synchronisieren
|
||||
- [[sed]] - Gefundene Dateien bearbeiten
|
||||
- [[awk]] - Ausgabe von find verarbeiten
|
||||
@@ -0,0 +1,127 @@
|
||||
# fstab - Credentials sicher speichern
|
||||
|
||||
Zugangsdaten (Benutzername/Passwort) sollten nicht im Klartext in `/etc/fstab` stehen.
|
||||
|
||||
## Credentials-Datei verwenden
|
||||
|
||||
Viele Treiber wie `cifs` oder `smbfs` unterstützen separate Credential-Dateien.
|
||||
|
||||
### fstab-Eintrag
|
||||
|
||||
```fstab
|
||||
//server/share /mnt/share cifs credentials=/etc/samba/credentials,iocharset=utf8,uid=1000,gid=1000 0 0
|
||||
```
|
||||
|
||||
### Credentials-Datei erstellen
|
||||
|
||||
**/etc/samba/credentials:**
|
||||
```
|
||||
username=meinuser
|
||||
password=meinpasswort
|
||||
domain=meinedomain
|
||||
```
|
||||
|
||||
### Datei absichern
|
||||
|
||||
```bash
|
||||
sudo chmod 600 /etc/samba/credentials
|
||||
sudo chown root:root /etc/samba/credentials
|
||||
```
|
||||
|
||||
Nur root kann die Datei lesen, `/etc/fstab` enthält keine Secrets.
|
||||
|
||||
## Kernel Keyring nutzen
|
||||
|
||||
Für temporäre Mounts (z.B. bei CIFS):
|
||||
|
||||
```bash
|
||||
cifscreds add -u meinuser servername
|
||||
```
|
||||
|
||||
Dann kann der Mount in fstab ohne Passwort erfolgen - der Kernel holt die Daten aus dem Keyring.
|
||||
|
||||
**Hinweis:** Funktioniert hauptsächlich für interaktive Sessions, nicht für automatische Boot-Mounts.
|
||||
|
||||
## Systemd-Units verwenden
|
||||
|
||||
Statt `/etc/fstab` kann man systemd `.mount`-Units mit Credentials nutzen.
|
||||
|
||||
**Beispiel:** `/etc/systemd/system/mnt-share.mount`
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=SMB Share Mount
|
||||
|
||||
[Mount]
|
||||
What=//server/share
|
||||
Where=/mnt/share
|
||||
Type=cifs
|
||||
Options=credentials=/etc/samba/credentials,iocharset=utf8,uid=1000,gid=1000
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Aktivieren:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable mnt-share.mount
|
||||
sudo systemctl start mnt-share.mount
|
||||
```
|
||||
|
||||
## Kerberos-Authentifizierung
|
||||
|
||||
Für Netzwerke mit Active Directory oder Kerberos:
|
||||
|
||||
### NFS mit Kerberos
|
||||
|
||||
```fstab
|
||||
server:/export /mnt/nfs nfs sec=krb5,rw 0 0
|
||||
```
|
||||
|
||||
### CIFS mit Kerberos
|
||||
|
||||
```fstab
|
||||
//server/share /mnt/share cifs sec=krb5,multiuser,rw 0 0
|
||||
```
|
||||
|
||||
Keine Passwörter nötig - Authentifizierung über Kerberos-Tickets.
|
||||
|
||||
## Secrets-Management-Systeme
|
||||
|
||||
Für Produktivumgebungen mit höheren Sicherheitsanforderungen:
|
||||
|
||||
- **HashiCorp Vault** - zentrales Secrets-Management
|
||||
- **AWS Secrets Manager** - für Cloud-Umgebungen
|
||||
- **GPG-verschlüsselte Dateien** - lokal verschlüsselt
|
||||
|
||||
Beispiel mit GPG:
|
||||
|
||||
```bash
|
||||
# Credentials verschlüsselt speichern
|
||||
echo "username=user\npassword=pass" | gpg -e -r you@example.com > /etc/samba/credentials.gpg
|
||||
|
||||
# In Mount-Skript entschlüsseln
|
||||
gpg -d /etc/samba/credentials.gpg > /tmp/credentials
|
||||
mount -t cifs -o credentials=/tmp/credentials //server/share /mnt/share
|
||||
rm /tmp/credentials
|
||||
```
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
| Methode | Sicherheit | Komplexität | Anwendungsfall |
|
||||
|---------|-----------|-------------|----------------|
|
||||
| Credentials-Datei | Gut | Niedrig | Standard für CIFS/SMB |
|
||||
| Kernel Keyring | Mittel | Mittel | Interaktive Sessions |
|
||||
| Kerberos | Sehr gut | Hoch | Enterprise/AD-Umgebungen |
|
||||
| Systemd-Credentials | Sehr gut | Mittel | Moderne Systeme |
|
||||
| Secrets Manager | Sehr gut | Hoch | Produktivumgebungen |
|
||||
|
||||
**Empfehlung:** Für den Alltag ist eine separate Credentials-Datei mit restriktiven Rechten (600) der beste Kompromiss aus Sicherheit und Einfachheit.
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[Symlinks]] - Symbolische Links erstellen
|
||||
- [[Dateiberechtigungen]] - Dateien absichern mit chmod/chown
|
||||
- [[lsblk]] - Block-Geräte anzeigen
|
||||
@@ -0,0 +1,202 @@
|
||||
# grep - Textsuche in Dateien
|
||||
|
||||
Der `grep`-Befehl durchsucht Dateien oder Textströme nach Mustern (Strings oder reguläre Ausdrücke).
|
||||
|
||||
## Grundsyntax
|
||||
|
||||
```bash
|
||||
grep [OPTIONEN] MUSTER [DATEI...]
|
||||
```
|
||||
|
||||
## Einfache Suche
|
||||
|
||||
```bash
|
||||
grep "suchtext" datei.txt
|
||||
```
|
||||
|
||||
In mehreren Dateien:
|
||||
|
||||
```bash
|
||||
grep "suchtext" *.txt
|
||||
```
|
||||
|
||||
Rekursiv in Verzeichnissen:
|
||||
|
||||
```bash
|
||||
grep -r "suchtext" /pfad/zum/verzeichnis
|
||||
```
|
||||
|
||||
## Wichtige Optionen
|
||||
|
||||
### Groß-/Kleinschreibung
|
||||
|
||||
```bash
|
||||
grep -i "suchtext" datei.txt # case-insensitive
|
||||
```
|
||||
|
||||
### Zeilen mit Kontext
|
||||
|
||||
```bash
|
||||
grep -A 3 "suchtext" datei.txt # 3 Zeilen danach
|
||||
grep -B 3 "suchtext" datei.txt # 3 Zeilen davor
|
||||
grep -C 3 "suchtext" datei.txt # 3 Zeilen davor und danach
|
||||
```
|
||||
|
||||
### Nur Dateinamen anzeigen
|
||||
|
||||
```bash
|
||||
grep -l "suchtext" *.txt # Dateien mit Treffer
|
||||
grep -L "suchtext" *.txt # Dateien ohne Treffer
|
||||
```
|
||||
|
||||
### Zeilennummern anzeigen
|
||||
|
||||
```bash
|
||||
grep -n "suchtext" datei.txt
|
||||
```
|
||||
|
||||
### Anzahl der Treffer
|
||||
|
||||
```bash
|
||||
grep -c "suchtext" datei.txt
|
||||
```
|
||||
|
||||
### Invertierte Suche (nicht enthalten)
|
||||
|
||||
```bash
|
||||
grep -v "suchtext" datei.txt
|
||||
```
|
||||
|
||||
Zeigt alle Zeilen, die den Suchtext NICHT enthalten.
|
||||
|
||||
### Ganzes Wort
|
||||
|
||||
```bash
|
||||
grep -w "wort" datei.txt
|
||||
```
|
||||
|
||||
Findet "wort", aber nicht "worte" oder "hauptwort".
|
||||
|
||||
## Reguläre Ausdrücke
|
||||
|
||||
### Einfache Regex (Basic)
|
||||
|
||||
```bash
|
||||
grep "^Start" datei.txt # Zeilen, die mit "Start" beginnen
|
||||
grep "Ende$" datei.txt # Zeilen, die mit "Ende" enden
|
||||
grep "^$" datei.txt # Leere Zeilen
|
||||
```
|
||||
|
||||
### Extended Regex
|
||||
|
||||
```bash
|
||||
grep -E "fehler|warnung" datei.txt # fehler ODER warnung
|
||||
grep -E "[0-9]{3}-[0-9]{4}" datei.txt # Telefonnummern
|
||||
grep -E "^(root|admin)" /etc/passwd # Zeilen mit root oder admin am Anfang
|
||||
```
|
||||
|
||||
### Perl-kompatible Regex
|
||||
|
||||
```bash
|
||||
grep -P "\d{3}-\d{4}" datei.txt
|
||||
```
|
||||
|
||||
## Praktische Anwendungsfälle
|
||||
|
||||
### Logfiles durchsuchen
|
||||
|
||||
```bash
|
||||
grep -i "error" /var/log/syslog
|
||||
grep -E "error|warning|critical" /var/log/syslog
|
||||
```
|
||||
|
||||
### Mit Zeitstempel
|
||||
|
||||
```bash
|
||||
grep "2025-11-07" /var/log/application.log
|
||||
```
|
||||
|
||||
### Konfigurationsdateien
|
||||
|
||||
```bash
|
||||
# Alle nicht-kommentierten Zeilen
|
||||
grep -v "^#" /etc/ssh/sshd_config | grep -v "^$"
|
||||
```
|
||||
|
||||
### In komprimierten Dateien
|
||||
|
||||
```bash
|
||||
zgrep "suchtext" datei.log.gz
|
||||
```
|
||||
|
||||
### Mit find kombinieren
|
||||
|
||||
```bash
|
||||
find . -name "*.log" -exec grep -l "ERROR" {} +
|
||||
```
|
||||
|
||||
### Mehrere Muster aus Datei
|
||||
|
||||
```bash
|
||||
grep -f muster.txt datei.txt
|
||||
```
|
||||
|
||||
**muster.txt:**
|
||||
```
|
||||
fehler
|
||||
warnung
|
||||
critical
|
||||
```
|
||||
|
||||
## Pipe-Verwendung
|
||||
|
||||
```bash
|
||||
ps aux | grep firefox
|
||||
cat datei.txt | grep -v "^#" | grep "wichtig"
|
||||
dmesg | grep -i usb
|
||||
```
|
||||
|
||||
## Farbige Ausgabe
|
||||
|
||||
```bash
|
||||
grep --color=auto "suchtext" datei.txt
|
||||
```
|
||||
|
||||
Alias in `.bashrc` setzen:
|
||||
|
||||
```bash
|
||||
alias grep='grep --color=auto'
|
||||
```
|
||||
|
||||
## Alternative Tools
|
||||
|
||||
- **ripgrep (rg)** - sehr schnell, modern, empfohlen
|
||||
- **ag (The Silver Searcher)** - schneller als grep
|
||||
- **ack** - für Code-Suche optimiert
|
||||
|
||||
Beispiel mit ripgrep:
|
||||
|
||||
```bash
|
||||
rg "suchtext" /pfad # automatisch rekursiv, ignoriert .gitignore
|
||||
```
|
||||
|
||||
## Zusammenfassung wichtiger Optionen
|
||||
|
||||
| Option | Beschreibung |
|
||||
|--------|--------------|
|
||||
| `-i` | Case-insensitive |
|
||||
| `-r` | Rekursiv |
|
||||
| `-n` | Mit Zeilennummern |
|
||||
| `-c` | Anzahl der Treffer |
|
||||
| `-l` | Nur Dateinamen |
|
||||
| `-v` | Invertiert (nicht enthalten) |
|
||||
| `-w` | Ganzes Wort |
|
||||
| `-E` | Extended Regex |
|
||||
| `-A/-B/-C` | Kontext anzeigen |
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[find]] - Dateien nach Namen/Eigenschaften suchen
|
||||
- [[sed]] - Stream-Editor für Textmanipulation
|
||||
- [[awk]] - Textverarbeitung und Datenextraktion
|
||||
- [[ls]] - Ausgabe von ls filtern
|
||||
@@ -0,0 +1,390 @@
|
||||
# ls - Dateien und Verzeichnisse auflisten
|
||||
|
||||
Der `ls`-Befehl listet Dateien und Verzeichnisse auf und zeigt deren Eigenschaften.
|
||||
|
||||
## Grundsyntax
|
||||
|
||||
```bash
|
||||
ls [OPTIONEN] [PFAD...]
|
||||
```
|
||||
|
||||
## Grundlegende Verwendung
|
||||
|
||||
### Einfache Auflistung
|
||||
|
||||
```bash
|
||||
ls # Aktuelles Verzeichnis
|
||||
ls /pfad/zum/ordner # Bestimmtes Verzeichnis
|
||||
ls datei.txt # Einzelne Datei
|
||||
```
|
||||
|
||||
### Versteckte Dateien anzeigen
|
||||
|
||||
```bash
|
||||
ls -a # Alle Dateien (inkl. .dotfiles)
|
||||
ls -A # Alle außer . und ..
|
||||
```
|
||||
|
||||
## Detaillierte Ausgabe
|
||||
|
||||
### Long Format (-l)
|
||||
|
||||
```bash
|
||||
ls -l
|
||||
```
|
||||
|
||||
Beispielausgabe:
|
||||
```
|
||||
-rw-r--r-- 1 alice developers 1234 Nov 7 10:00 datei.txt
|
||||
drwxr-xr-x 2 alice developers 4096 Nov 7 09:30 ordner
|
||||
lrwxrwxrwx 1 alice developers 15 Nov 7 08:00 link -> /pfad/zu/ziel
|
||||
```
|
||||
|
||||
Spalten:
|
||||
- **1. Zeichen**: Typ (`-` = Datei, `d` = Verzeichnis, `l` = Link)
|
||||
- **2-10**: Rechte (rwx für User, Group, Others)
|
||||
- **Zahl**: Anzahl Hardlinks
|
||||
- **User**: Eigentümer
|
||||
- **Group**: Gruppe
|
||||
- **Größe**: in Bytes
|
||||
- **Datum/Zeit**: letzte Änderung
|
||||
- **Name**: Dateiname
|
||||
|
||||
### Menschenlesbare Größen (-h)
|
||||
|
||||
```bash
|
||||
ls -lh
|
||||
```
|
||||
|
||||
Beispielausgabe:
|
||||
```
|
||||
-rw-r--r-- 1 user staff 12K Nov 7 10:00 file.txt
|
||||
-rw-r--r-- 1 user staff 1.2M Nov 7 09:30 big.dat
|
||||
drwxr-xr-x 2 user staff 4.0K Nov 7 08:00 ordner
|
||||
```
|
||||
|
||||
Größen werden in KB, MB, GB statt Bytes angezeigt.
|
||||
|
||||
## Sortierung
|
||||
|
||||
### Nach Name (Standard)
|
||||
|
||||
```bash
|
||||
ls # Alphabetisch
|
||||
ls -r # Umgekehrt
|
||||
```
|
||||
|
||||
### Nach Änderungsdatum
|
||||
|
||||
```bash
|
||||
ls -lt # Neueste zuerst
|
||||
ls -ltr # Älteste zuerst
|
||||
```
|
||||
|
||||
### Nach Größe
|
||||
|
||||
```bash
|
||||
ls -lS # Größte zuerst
|
||||
ls -lSr # Kleinste zuerst
|
||||
```
|
||||
|
||||
### Nach Erweiterung
|
||||
|
||||
```bash
|
||||
ls -lX # Gruppiert nach Dateityp
|
||||
```
|
||||
|
||||
## Rekursive Auflistung
|
||||
|
||||
```bash
|
||||
ls -R # Alle Unterverzeichnisse
|
||||
ls -R /pfad # Ab bestimmtem Pfad
|
||||
```
|
||||
|
||||
## Nur bestimmte Dateien
|
||||
|
||||
### Mit Wildcards
|
||||
|
||||
```bash
|
||||
ls *.txt # Alle .txt Dateien
|
||||
ls *.{jpg,png} # Alle .jpg und .png
|
||||
ls file[0-9]* # file0, file1, file2, ...
|
||||
```
|
||||
|
||||
### Nur Verzeichnisse
|
||||
|
||||
```bash
|
||||
ls -d */ # Nur Verzeichnisse
|
||||
ls -ld */ # Mit Details
|
||||
```
|
||||
|
||||
### Nur Dateien (keine Verzeichnisse)
|
||||
|
||||
```bash
|
||||
ls -p | grep -v /
|
||||
```
|
||||
|
||||
## Farben
|
||||
|
||||
```bash
|
||||
ls --color=auto # Farbige Ausgabe
|
||||
ls --color=never # Ohne Farben
|
||||
ls --color=always # Immer Farben (auch in Pipes)
|
||||
```
|
||||
|
||||
Typische Farben:
|
||||
- **Blau**: Verzeichnisse
|
||||
- **Grün**: Ausführbare Dateien
|
||||
- **Cyan**: Symbolische Links
|
||||
- **Rot**: Archive
|
||||
- **Gelb**: Devices
|
||||
|
||||
## Spezielle Formate
|
||||
|
||||
### Einzelne Spalte
|
||||
|
||||
```bash
|
||||
ls -1 # Eine Datei pro Zeile
|
||||
```
|
||||
|
||||
### Komma-getrennt
|
||||
|
||||
```bash
|
||||
ls -m # Komma-getrennte Liste
|
||||
```
|
||||
|
||||
### Mit Inode-Nummern
|
||||
|
||||
```bash
|
||||
ls -i # Zeigt Inode-Nummern
|
||||
```
|
||||
|
||||
### Numerische UIDs/GIDs
|
||||
|
||||
```bash
|
||||
ls -n # User/Group als Zahlen statt Namen
|
||||
```
|
||||
|
||||
## Dateigrößen analysieren
|
||||
|
||||
### Größe einzelner Dateien
|
||||
|
||||
```bash
|
||||
ls -lh datei.txt
|
||||
```
|
||||
|
||||
Ausgabe:
|
||||
```
|
||||
-rw-r--r-- 1 user staff 12K Nov 7 10:00 datei.txt
|
||||
```
|
||||
|
||||
### Größe mit stat
|
||||
|
||||
Nur die Größe in Bytes:
|
||||
|
||||
```bash
|
||||
stat -c%s datei.txt
|
||||
```
|
||||
|
||||
Mit Dateiname:
|
||||
|
||||
```bash
|
||||
stat -c "%s %n" *
|
||||
```
|
||||
|
||||
### Größe von Verzeichnissen
|
||||
|
||||
`ls` zeigt nur die Größe des Verzeichniseintrags (meist 4K), nicht den Inhalt!
|
||||
|
||||
Für echte Verzeichnisgröße nutze `du`:
|
||||
|
||||
```bash
|
||||
du -sh ordner/ # Gesamtgröße
|
||||
du -h --max-depth=1 # Größen aller Unterordner
|
||||
```
|
||||
|
||||
Beispielausgabe:
|
||||
```
|
||||
200M ./Bilder
|
||||
1.3G ./Videos
|
||||
50K ./Dokumente
|
||||
1.5G .
|
||||
```
|
||||
|
||||
Mit 1000er-Schritten statt 1024er:
|
||||
|
||||
```bash
|
||||
du -h --si --max-depth=1
|
||||
```
|
||||
|
||||
### Nach Größe sortiert
|
||||
|
||||
```bash
|
||||
du -sh * | sort -h # Alle Dateien/Ordner sortiert
|
||||
ls -lhS # Nur Dateien, größte zuerst
|
||||
```
|
||||
|
||||
### Größte Dateien finden
|
||||
|
||||
Top 10 größte Dateien:
|
||||
|
||||
```bash
|
||||
du -ah . | sort -rh | head -n 10
|
||||
```
|
||||
|
||||
Mit [[find]]:
|
||||
|
||||
```bash
|
||||
find . -type f -exec du -h {} + | sort -rh | head -n 10
|
||||
```
|
||||
|
||||
### Speicherplatznutzung überwachen
|
||||
|
||||
Gesamter Speicherplatz:
|
||||
|
||||
```bash
|
||||
df -h # Dateisysteme
|
||||
df -h /home # Bestimmter Mountpoint
|
||||
```
|
||||
|
||||
## Zeitstempel
|
||||
|
||||
### Änderungszeit (Standard)
|
||||
|
||||
```bash
|
||||
ls -l # Zeigt mtime (modification time)
|
||||
```
|
||||
|
||||
### Zugriffszeit
|
||||
|
||||
```bash
|
||||
ls -lu # Zeigt atime (access time)
|
||||
```
|
||||
|
||||
### Statusänderungszeit
|
||||
|
||||
```bash
|
||||
ls -lc # Zeigt ctime (change time)
|
||||
```
|
||||
|
||||
### Mit vollständigem Zeitstempel
|
||||
|
||||
```bash
|
||||
ls -l --time-style=full-iso
|
||||
ls -l --time-style=long-iso
|
||||
ls -l --time-style=iso
|
||||
```
|
||||
|
||||
## Praktische Kombinationen
|
||||
|
||||
### Übersichtliche Dateiliste
|
||||
|
||||
```bash
|
||||
ls -lhA # Details, lesbar, alle außer . und ..
|
||||
ls -lhAtr # Dazu sortiert nach Datum, älteste zuerst
|
||||
```
|
||||
|
||||
### Schnelle Dateisuche
|
||||
|
||||
```bash
|
||||
ls -la | grep datei # Suche in aktueller Liste
|
||||
```
|
||||
|
||||
### Nur Größen von Verzeichnissen
|
||||
|
||||
```bash
|
||||
du -sh */ # Alle Unterverzeichnisse
|
||||
```
|
||||
|
||||
### Dateien nach Änderung heute
|
||||
|
||||
```bash
|
||||
ls -lt | head # Neueste Dateien
|
||||
```
|
||||
|
||||
### Ausführbare Dateien finden
|
||||
|
||||
```bash
|
||||
ls -l | grep '^-..x'
|
||||
```
|
||||
|
||||
### Große Dateien finden
|
||||
|
||||
```bash
|
||||
ls -lhS | head -n 10 # Top 10 größte Dateien
|
||||
```
|
||||
|
||||
### Versteckte Dateien zählen
|
||||
|
||||
```bash
|
||||
ls -A | wc -l
|
||||
```
|
||||
|
||||
## Nützliche Aliases
|
||||
|
||||
Setze in `~/.bashrc`:
|
||||
|
||||
```bash
|
||||
alias ll='ls -lhA'
|
||||
alias la='ls -A'
|
||||
alias l='ls -CF'
|
||||
alias lt='ls -lhAtr'
|
||||
alias lsize='ls -lhS'
|
||||
```
|
||||
|
||||
## Zusammen mit anderen Befehlen
|
||||
|
||||
### Mit find
|
||||
|
||||
```bash
|
||||
find . -name "*.log" -exec ls -lh {} \;
|
||||
```
|
||||
|
||||
### Mit grep
|
||||
|
||||
```bash
|
||||
ls -la | grep "Nov 7" # Dateien von heute
|
||||
ls -la | grep "^d" # Nur Verzeichnisse
|
||||
```
|
||||
|
||||
### Mit awk
|
||||
|
||||
```bash
|
||||
ls -l | awk '{print $9, $5}' # Name und Größe
|
||||
```
|
||||
|
||||
### Mit xargs
|
||||
|
||||
```bash
|
||||
ls *.txt | xargs rm # VORSICHT: Löscht alle .txt
|
||||
```
|
||||
|
||||
## Fehler vermeiden
|
||||
|
||||
### Dateien mit Leerzeichen
|
||||
|
||||
```bash
|
||||
# FALSCH
|
||||
ls *.txt | xargs rm
|
||||
|
||||
# RICHTIG
|
||||
find . -name "*.txt" -print0 | xargs -0 rm
|
||||
```
|
||||
|
||||
### Alias-Konflikte
|
||||
|
||||
Viele Systeme haben `ls` als Alias mit `--color=auto` definiert. Um den echten Befehl zu nutzen:
|
||||
|
||||
```bash
|
||||
\ls # Umgeht Alias
|
||||
command ls # Umgeht Alias
|
||||
/bin/ls # Direkter Pfad
|
||||
```
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[find]] - Erweiterte Dateisuche mit Kriterien
|
||||
- [[grep]] - Ausgabe filtern
|
||||
- [[Dateiberechtigungen]] - Bedeutung der Rechtespalten
|
||||
- [[lsblk]] - Block-Geräte statt Dateien
|
||||
- [[du]] - Detaillierte Größenanalyse
|
||||
@@ -0,0 +1,177 @@
|
||||
# lsblk - Block-Geräte auflisten
|
||||
|
||||
Der Befehl `lsblk` (list block devices) zeigt eine hierarchische Übersicht aller Blockgeräte: Festplatten, SSDs, USB-Sticks, Partitionen, LVMs, RAID-Geräte usw.
|
||||
|
||||
## Grundsyntax
|
||||
|
||||
```bash
|
||||
lsblk [OPTIONEN] [GERÄTE...]
|
||||
```
|
||||
|
||||
Ohne Parameter werden alle erkannten Blockgeräte in Baumstruktur angezeigt.
|
||||
|
||||
## Typische Ausgabe
|
||||
|
||||
```bash
|
||||
lsblk
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
sda 8:0 0 512G 0 disk
|
||||
├─sda1 8:1 0 512M 0 part /boot/efi
|
||||
├─sda2 8:2 0 64G 0 part /
|
||||
└─sda3 8:3 0 447.5G 0 part /home
|
||||
sdb 8:16 1 128G 0 disk
|
||||
└─sdb1 8:17 1 128G 0 part /media/usb
|
||||
```
|
||||
|
||||
Spalten:
|
||||
- **NAME** = Gerätename (sda, sdb, ...)
|
||||
- **SIZE** = Größe
|
||||
- **TYPE** = Art (disk, part, rom, lvm ...)
|
||||
- **MOUNTPOINTS** = Einbindungspunkt im Dateisystem
|
||||
|
||||
## Wichtige Optionen
|
||||
|
||||
### Bestimmte Spalten anzeigen
|
||||
|
||||
```bash
|
||||
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
NAME FSTYPE SIZE MOUNTPOINT
|
||||
sda 512G
|
||||
├─sda1 vfat 512M /boot/efi
|
||||
├─sda2 ext4 64G /
|
||||
└─sda3 ext4 447.5G /home
|
||||
```
|
||||
|
||||
### Dateisystemtypen anzeigen
|
||||
|
||||
```bash
|
||||
lsblk -f
|
||||
```
|
||||
|
||||
Zeigt Dateisystemtyp, UUID und Label.
|
||||
|
||||
### Nur Geräte ohne Partitionen
|
||||
|
||||
```bash
|
||||
lsblk -d
|
||||
```
|
||||
|
||||
Zeigt nur die Hauptgeräte (`sda`, `sdb`), keine Partitionen.
|
||||
|
||||
### Alle Geräte inklusive leere
|
||||
|
||||
```bash
|
||||
lsblk -a
|
||||
```
|
||||
|
||||
Zeigt auch Geräte ohne Medium (z.B. leere CD-Laufwerke).
|
||||
|
||||
### Mit UUIDs und Labels
|
||||
|
||||
```bash
|
||||
lsblk -o NAME,SIZE,UUID,LABEL,MOUNTPOINT
|
||||
```
|
||||
|
||||
Wichtig für eindeutige Identifizierung in `/etc/fstab`.
|
||||
|
||||
### Nur Namen ausgeben
|
||||
|
||||
```bash
|
||||
lsblk -n -o NAME
|
||||
```
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
sda
|
||||
sda1
|
||||
sda2
|
||||
sda3
|
||||
sdb
|
||||
sdb1
|
||||
```
|
||||
|
||||
Praktisch für Skripte.
|
||||
|
||||
### Listen- oder JSON-Format
|
||||
|
||||
```bash
|
||||
lsblk -l # Listenformat
|
||||
lsblk -J # JSON-Format
|
||||
```
|
||||
|
||||
## Praktische Anwendungsfälle
|
||||
|
||||
### Herausfinden, welche Geräte angeschlossen sind
|
||||
|
||||
```bash
|
||||
lsblk
|
||||
```
|
||||
|
||||
### Prüfen, welche Partitionen wohin gemountet sind
|
||||
|
||||
```bash
|
||||
lsblk -o NAME,SIZE,MOUNTPOINT
|
||||
```
|
||||
|
||||
### Dateisystemtypen ermitteln
|
||||
|
||||
```bash
|
||||
lsblk -f
|
||||
```
|
||||
|
||||
### Neu eingesteckten USB-Stick identifizieren
|
||||
|
||||
Vorher:
|
||||
```bash
|
||||
lsblk
|
||||
```
|
||||
|
||||
Stick einstecken, dann:
|
||||
```bash
|
||||
lsblk
|
||||
```
|
||||
|
||||
Das neue Gerät (z.B. `sdb1`) erscheint.
|
||||
|
||||
### UUIDs für fstab ermitteln
|
||||
|
||||
```bash
|
||||
lsblk -o NAME,UUID,MOUNTPOINT
|
||||
```
|
||||
|
||||
### Geräte mit bestimmtem Dateisystem finden
|
||||
|
||||
```bash
|
||||
lsblk -o NAME,FSTYPE,SIZE | grep ext4
|
||||
```
|
||||
|
||||
## Zusammenfassung wichtiger Optionen
|
||||
|
||||
| Option | Beschreibung |
|
||||
|--------|--------------|
|
||||
| `lsblk` | Baumstruktur aller Blockgeräte |
|
||||
| `lsblk -f` | Mit Dateisystemtypen |
|
||||
| `lsblk -d` | Nur Hauptgeräte |
|
||||
| `lsblk -a` | Alle inkl. leere Geräte |
|
||||
| `lsblk -o SPALTEN` | Bestimmte Spalten |
|
||||
| `lsblk -l` | Listenformat |
|
||||
| `lsblk -J` | JSON-Format |
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[ls]] - Dateien und Verzeichnisse auflisten
|
||||
- [[find]] - Dateien suchen
|
||||
- [[fstab Credentials]] - Geräte automatisch einbinden
|
||||
- [[Symlinks]] - Verknüpfungen zu Geräten
|
||||
- [[Dateiberechtigungen]] - Rechte von Geräten prüfen
|
||||
@@ -0,0 +1,275 @@
|
||||
# rsync - Dateien synchronisieren
|
||||
|
||||
Der `rsync`-Befehl synchronisiert Dateien und Verzeichnisse effizient zwischen verschiedenen Orten (lokal oder über Netzwerk).
|
||||
|
||||
## Grundsyntax
|
||||
|
||||
```bash
|
||||
rsync [OPTIONEN] QUELLE ZIEL
|
||||
```
|
||||
|
||||
## Grundlegende Optionen
|
||||
|
||||
Die häufigste Kombination:
|
||||
|
||||
```bash
|
||||
rsync -av quelle/ ziel/
|
||||
```
|
||||
|
||||
- `-a` = archive (behält Rechte, Zeitstempel, Symlinks)
|
||||
- `-v` = verbose (zeigt Details)
|
||||
|
||||
## Lokale Synchronisation
|
||||
|
||||
### Verzeichnis synchronisieren
|
||||
|
||||
```bash
|
||||
rsync -av /quelle/verzeichnis/ /ziel/verzeichnis/
|
||||
```
|
||||
|
||||
**Wichtig:** Trailing Slash `/` macht einen Unterschied!
|
||||
|
||||
```bash
|
||||
rsync -av quelle/ ziel/ # Inhalt von quelle/ nach ziel/
|
||||
rsync -av quelle ziel/ # quelle/ als Unterordner in ziel/quelle/
|
||||
```
|
||||
|
||||
## Über Netzwerk (SSH)
|
||||
|
||||
### Zu Remote-Server
|
||||
|
||||
```bash
|
||||
rsync -av /lokaler/pfad/ user@server:/remote/pfad/
|
||||
```
|
||||
|
||||
### Von Remote-Server
|
||||
|
||||
```bash
|
||||
rsync -av user@server:/remote/pfad/ /lokaler/pfad/
|
||||
```
|
||||
|
||||
### Anderen SSH-Port
|
||||
|
||||
```bash
|
||||
rsync -av -e "ssh -p 2222" /lokal/ user@server:/remote/
|
||||
```
|
||||
|
||||
## Wichtige Optionen
|
||||
|
||||
### Fortschritt anzeigen
|
||||
|
||||
```bash
|
||||
rsync -av --progress quelle/ ziel/
|
||||
```
|
||||
|
||||
### Dry-run (simulieren)
|
||||
|
||||
```bash
|
||||
rsync -avn quelle/ ziel/
|
||||
```
|
||||
|
||||
- `-n` = dry-run (nichts ändern, nur anzeigen)
|
||||
|
||||
### Dateien löschen im Ziel
|
||||
|
||||
```bash
|
||||
rsync -av --delete quelle/ ziel/
|
||||
```
|
||||
|
||||
Löscht Dateien im Ziel, die in der Quelle nicht existieren.
|
||||
|
||||
### Kompression (für Netzwerk)
|
||||
|
||||
```bash
|
||||
rsync -avz quelle/ user@server:/remote/
|
||||
```
|
||||
|
||||
- `-z` = compress (während Übertragung)
|
||||
|
||||
### Teilweise übertragene Dateien behalten
|
||||
|
||||
```bash
|
||||
rsync -av --partial quelle/ ziel/
|
||||
```
|
||||
|
||||
Nützlich bei unterbrochenen Übertragungen.
|
||||
|
||||
### Bandbreite begrenzen
|
||||
|
||||
```bash
|
||||
rsync -av --bwlimit=1000 quelle/ ziel/
|
||||
```
|
||||
|
||||
Begrenzt auf 1000 KB/s.
|
||||
|
||||
## Dateien ausschließen
|
||||
|
||||
### Einzelne Muster
|
||||
|
||||
```bash
|
||||
rsync -av --exclude='*.tmp' --exclude='.git' quelle/ ziel/
|
||||
```
|
||||
|
||||
### Aus Datei
|
||||
|
||||
```bash
|
||||
rsync -av --exclude-from=exclude.txt quelle/ ziel/
|
||||
```
|
||||
|
||||
**exclude.txt:**
|
||||
```
|
||||
*.tmp
|
||||
*.log
|
||||
.git/
|
||||
node_modules/
|
||||
```
|
||||
|
||||
### Nur bestimmte Dateien
|
||||
|
||||
```bash
|
||||
rsync -av --include='*.pdf' --exclude='*' quelle/ ziel/
|
||||
```
|
||||
|
||||
## Praktische Beispiele
|
||||
|
||||
### Backup erstellen
|
||||
|
||||
```bash
|
||||
rsync -av --delete /home/user/dokumente/ /backup/dokumente/
|
||||
```
|
||||
|
||||
### Backup mit Zeitstempel
|
||||
|
||||
```bash
|
||||
rsync -av /quelle/ /backup/backup-$(date +%Y%m%d)/
|
||||
```
|
||||
|
||||
### Nur geänderte Dateien kopieren
|
||||
|
||||
```bash
|
||||
rsync -av --update quelle/ ziel/
|
||||
```
|
||||
|
||||
Überschreibt nur, wenn Quelle neuer ist.
|
||||
|
||||
### Große Dateien übertragen
|
||||
|
||||
```bash
|
||||
rsync -av --progress --partial-dir=.rsync-partial quelle/ ziel/
|
||||
```
|
||||
|
||||
### Backup auf NAS
|
||||
|
||||
```bash
|
||||
rsync -av --delete /home/user/ user@nas:/backup/user/
|
||||
```
|
||||
|
||||
### Website hochladen
|
||||
|
||||
```bash
|
||||
rsync -avz --delete website/ user@webserver:/var/www/html/
|
||||
```
|
||||
|
||||
### Mit Ausschlüssen
|
||||
|
||||
```bash
|
||||
rsync -av --delete \
|
||||
--exclude='node_modules' \
|
||||
--exclude='.git' \
|
||||
--exclude='*.log' \
|
||||
projekt/ /backup/projekt/
|
||||
```
|
||||
|
||||
## Inkrementelles Backup
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
CURRENT=/backup/current
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
rsync -av --delete --link-dest=$CURRENT /quelle/ /backup/$TIMESTAMP/
|
||||
rm -f $CURRENT
|
||||
ln -s $TIMESTAMP $CURRENT
|
||||
```
|
||||
|
||||
Erstellt platzsparende Backups durch Hardlinks.
|
||||
|
||||
## Rechte und Eigentümer
|
||||
|
||||
### Rechte bewahren
|
||||
|
||||
```bash
|
||||
rsync -av quelle/ ziel/ # Standard mit -a
|
||||
```
|
||||
|
||||
### Als Root mit Original-Eigentümer
|
||||
|
||||
```bash
|
||||
sudo rsync -av quelle/ ziel/
|
||||
```
|
||||
|
||||
### Nur als aktueller User
|
||||
|
||||
```bash
|
||||
rsync -rlptv quelle/ ziel/
|
||||
```
|
||||
|
||||
Ohne `-o` und `-g` (Owner und Group).
|
||||
|
||||
## Fehler vermeiden
|
||||
|
||||
### Dry-run erst testen
|
||||
|
||||
```bash
|
||||
rsync -avn --delete quelle/ ziel/
|
||||
```
|
||||
|
||||
Prüfe die Ausgabe, bevor du wirklich synchronisierst!
|
||||
|
||||
### Slash bei Quelle beachten
|
||||
|
||||
```bash
|
||||
rsync -av quelle/ ziel/ # Inhalt synchronisieren
|
||||
rsync -av quelle ziel/ # Ordner synchronisieren
|
||||
```
|
||||
|
||||
### Mit --delete vorsichtig sein
|
||||
|
||||
```bash
|
||||
# FALSCH - löscht alles im Ziel!
|
||||
rsync -av --delete /leerer/ordner/ /wichtig/
|
||||
|
||||
# RICHTIG - erst prüfen
|
||||
rsync -avn --delete quelle/ ziel/
|
||||
```
|
||||
|
||||
## Vergleich mit anderen Tools
|
||||
|
||||
| Tool | Geschwindigkeit | Delta-Transfer | Netzwerk | Verschlüsselung |
|
||||
|------|----------------|----------------|----------|-----------------|
|
||||
| `rsync` | Schnell | Ja | SSH | Via SSH |
|
||||
| `scp` | Mittel | Nein | SSH | Ja |
|
||||
| `cp` | Sehr schnell | Nein | Nein | Nein |
|
||||
| `tar` | Mittel | Nein | Pipe möglich | Optional |
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Fortschritt detailliert
|
||||
|
||||
```bash
|
||||
rsync -av --progress --stats quelle/ ziel/
|
||||
```
|
||||
|
||||
### Nur Zusammenfassung
|
||||
|
||||
```bash
|
||||
rsync -av --stats quelle/ ziel/
|
||||
```
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[tar]] - Archive erstellen
|
||||
- [[find]] - Dateien für Backup finden
|
||||
- [[Symlinks]] - Links bleiben mit -a erhalten
|
||||
- [[Dateiberechtigungen]] - Rechte und Eigentümer nach rsync
|
||||
- [[ls]] - Übertragene Dateien anzeigen
|
||||
@@ -0,0 +1,270 @@
|
||||
# sed - Stream Editor
|
||||
|
||||
Der `sed`-Befehl ist ein Stream-Editor für Textmanipulation. Er eignet sich besonders für Suchen-und-Ersetzen-Operationen.
|
||||
|
||||
## Grundsyntax
|
||||
|
||||
```bash
|
||||
sed [OPTIONEN] 'BEFEHL' [DATEI...]
|
||||
```
|
||||
|
||||
## Suchen und Ersetzen
|
||||
|
||||
### Grundlegendes Ersetzen
|
||||
|
||||
```bash
|
||||
sed 's/alt/neu/' datei.txt
|
||||
```
|
||||
|
||||
Ersetzt erste Vorkommen in jeder Zeile.
|
||||
|
||||
### Alle Vorkommen in Zeile
|
||||
|
||||
```bash
|
||||
sed 's/alt/neu/g' datei.txt
|
||||
```
|
||||
|
||||
- `g` = global (alle Vorkommen)
|
||||
|
||||
### Datei direkt ändern
|
||||
|
||||
```bash
|
||||
sed -i 's/alt/neu/g' datei.txt
|
||||
```
|
||||
|
||||
- `-i` = in-place (Datei wird geändert)
|
||||
|
||||
### Backup vor Änderung
|
||||
|
||||
```bash
|
||||
sed -i.bak 's/alt/neu/g' datei.txt
|
||||
```
|
||||
|
||||
Erstellt `datei.txt.bak` vor Änderung.
|
||||
|
||||
## Zeilen auswählen
|
||||
|
||||
### Bestimmte Zeile
|
||||
|
||||
```bash
|
||||
sed -n '5p' datei.txt # Nur Zeile 5
|
||||
sed '5d' datei.txt # Zeile 5 löschen
|
||||
sed '5s/alt/neu/' datei.txt # Nur in Zeile 5 ersetzen
|
||||
```
|
||||
|
||||
### Zeilenbereich
|
||||
|
||||
```bash
|
||||
sed -n '10,20p' datei.txt # Zeilen 10-20 anzeigen
|
||||
sed '10,20d' datei.txt # Zeilen 10-20 löschen
|
||||
```
|
||||
|
||||
### Letzte Zeile
|
||||
|
||||
```bash
|
||||
sed -n '$p' datei.txt # Letzte Zeile
|
||||
```
|
||||
|
||||
### Muster-basiert
|
||||
|
||||
```bash
|
||||
sed '/^#/d' datei.txt # Zeilen mit # am Anfang löschen
|
||||
sed '/ERROR/s/foo/bar/' datei.txt # Nur in Zeilen mit ERROR
|
||||
```
|
||||
|
||||
## Zeilen einfügen und anhängen
|
||||
|
||||
### Vor Zeile einfügen
|
||||
|
||||
```bash
|
||||
sed '3i\Neue Zeile' datei.txt
|
||||
```
|
||||
|
||||
### Nach Zeile anhängen
|
||||
|
||||
```bash
|
||||
sed '3a\Neue Zeile' datei.txt
|
||||
```
|
||||
|
||||
### Nach Muster
|
||||
|
||||
```bash
|
||||
sed '/TODO/a\WICHTIG: Bitte bearbeiten' datei.txt
|
||||
```
|
||||
|
||||
## Zeilen löschen
|
||||
|
||||
### Leere Zeilen
|
||||
|
||||
```bash
|
||||
sed '/^$/d' datei.txt
|
||||
```
|
||||
|
||||
### Kommentare
|
||||
|
||||
```bash
|
||||
sed '/^#/d' datei.txt
|
||||
```
|
||||
|
||||
### Mehrere Muster
|
||||
|
||||
```bash
|
||||
sed -e '/^#/d' -e '/^$/d' datei.txt
|
||||
```
|
||||
|
||||
## Reguläre Ausdrücke
|
||||
|
||||
### Erweiterte Regex
|
||||
|
||||
```bash
|
||||
sed -E 's/[0-9]{3}-[0-9]{4}/XXX-XXXX/g' datei.txt
|
||||
```
|
||||
|
||||
- `-E` = Extended Regex
|
||||
|
||||
### Gruppen und Backreferences
|
||||
|
||||
```bash
|
||||
sed 's/\([0-9]*\)-\([0-9]*\)/\2-\1/' datei.txt
|
||||
```
|
||||
|
||||
Vertauscht Zahlen vor und nach Bindestrich.
|
||||
|
||||
Mit `-E`:
|
||||
|
||||
```bash
|
||||
sed -E 's/([0-9]*)-([0-9]*)/\2-\1/' datei.txt
|
||||
```
|
||||
|
||||
## Praktische Beispiele
|
||||
|
||||
### Konfigurationsdatei ändern
|
||||
|
||||
```bash
|
||||
sed -i 's/^#Port 22/Port 2222/' /etc/ssh/sshd_config
|
||||
```
|
||||
|
||||
### IP-Adressen ersetzen
|
||||
|
||||
```bash
|
||||
sed 's/192\.168\.1\./10.0.0./g' config.txt
|
||||
```
|
||||
|
||||
### Zeilennummern hinzufügen
|
||||
|
||||
```bash
|
||||
sed = datei.txt | sed 'N;s/\n/\t/'
|
||||
```
|
||||
|
||||
### Kommentare und Leerzeilen entfernen
|
||||
|
||||
```bash
|
||||
sed -e '/^#/d' -e '/^$/d' config.conf
|
||||
```
|
||||
|
||||
### Mehrere Ersetzungen
|
||||
|
||||
```bash
|
||||
sed -e 's/foo/bar/g' -e 's/alt/neu/g' datei.txt
|
||||
```
|
||||
|
||||
### Case-insensitive Suche
|
||||
|
||||
```bash
|
||||
sed 's/fehler/ERROR/gI' datei.txt
|
||||
```
|
||||
|
||||
- `I` = case-insensitive
|
||||
|
||||
### Zeilen mit Muster extrahieren
|
||||
|
||||
```bash
|
||||
sed -n '/ERROR/p' logfile.txt
|
||||
```
|
||||
|
||||
Zeigt nur Zeilen mit "ERROR".
|
||||
|
||||
### Text zwischen Mustern
|
||||
|
||||
```bash
|
||||
sed -n '/START/,/END/p' datei.txt
|
||||
```
|
||||
|
||||
### Zeilen nummerieren
|
||||
|
||||
```bash
|
||||
sed = datei.txt
|
||||
```
|
||||
|
||||
## Mit Pipes
|
||||
|
||||
```bash
|
||||
cat datei.txt | sed 's/alt/neu/g' | grep wichtig
|
||||
ps aux | sed -n '1p;/firefox/p'
|
||||
```
|
||||
|
||||
## Mehrere Dateien
|
||||
|
||||
```bash
|
||||
sed -i 's/alt/neu/g' *.txt
|
||||
```
|
||||
|
||||
## Sed-Skripte
|
||||
|
||||
**script.sed:**
|
||||
```sed
|
||||
# Kommentare entfernen
|
||||
/^#/d
|
||||
# Leerzeilen entfernen
|
||||
/^$/d
|
||||
# foo durch bar ersetzen
|
||||
s/foo/bar/g
|
||||
```
|
||||
|
||||
Verwenden:
|
||||
|
||||
```bash
|
||||
sed -f script.sed datei.txt
|
||||
```
|
||||
|
||||
## Fehler vermeiden
|
||||
|
||||
### Backup erstellen
|
||||
|
||||
```bash
|
||||
sed -i.bak 's/alt/neu/g' wichtig.txt
|
||||
```
|
||||
|
||||
### Testen ohne Änderung
|
||||
|
||||
```bash
|
||||
sed 's/alt/neu/g' datei.txt > test.txt
|
||||
diff datei.txt test.txt
|
||||
```
|
||||
|
||||
### Spezialzeichen escapen
|
||||
|
||||
```bash
|
||||
# Punkt ist Wildcard
|
||||
sed 's/192.168.1.1/10.0.0.1/' config # FALSCH
|
||||
|
||||
# Punkt escapen
|
||||
sed 's/192\.168\.1\.1/10.0.0.1/' config # RICHTIG
|
||||
```
|
||||
|
||||
## Alternative Delimiter
|
||||
|
||||
Wenn Pfade mit `/` vorkommen:
|
||||
|
||||
```bash
|
||||
sed 's|/old/path|/new/path|g' datei.txt
|
||||
```
|
||||
|
||||
Statt `/` kann `|`, `#` oder andere Zeichen verwendet werden.
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[grep]] - Textsuche
|
||||
- [[awk]] - Komplexere Textverarbeitung
|
||||
- [[find]] - Dateien finden und mit sed bearbeiten
|
||||
- [[BASH Funktionen]] - sed in Funktionen verwenden
|
||||
@@ -0,0 +1,354 @@
|
||||
# tar - Archive erstellen und Software installieren
|
||||
|
||||
Der `tar`-Befehl (tape archive) erstellt und entpackt Archive. Oft in Kombination mit Kompression (gzip, bzip2, xz).
|
||||
|
||||
## Grundsyntax
|
||||
|
||||
```bash
|
||||
tar [OPTIONEN] [ARCHIV] [DATEIEN...]
|
||||
```
|
||||
|
||||
## Archive erstellen
|
||||
|
||||
### Einfaches Archiv (unkomprimiert)
|
||||
|
||||
```bash
|
||||
tar -cf archiv.tar verzeichnis/
|
||||
```
|
||||
|
||||
- `-c` = create (erstellen)
|
||||
- `-f` = file (Dateiname)
|
||||
|
||||
### Mit gzip-Kompression (.tar.gz)
|
||||
|
||||
```bash
|
||||
tar -czf archiv.tar.gz verzeichnis/
|
||||
```
|
||||
|
||||
- `-z` = gzip
|
||||
|
||||
### Mit bzip2-Kompression (.tar.bz2)
|
||||
|
||||
```bash
|
||||
tar -cjf archiv.tar.bz2 verzeichnis/
|
||||
```
|
||||
|
||||
- `-j` = bzip2
|
||||
|
||||
### Mit xz-Kompression (.tar.xz)
|
||||
|
||||
```bash
|
||||
tar -cJf archiv.tar.xz verzeichnis/
|
||||
```
|
||||
|
||||
- `-J` = xz (beste Kompression)
|
||||
|
||||
### Mit Fortschrittsanzeige
|
||||
|
||||
```bash
|
||||
tar -czf archiv.tar.gz verzeichnis/ -v
|
||||
```
|
||||
|
||||
- `-v` = verbose (Details anzeigen)
|
||||
|
||||
## Archive entpacken
|
||||
|
||||
### Automatische Kompressionserkennung
|
||||
|
||||
```bash
|
||||
tar -xf archiv.tar.gz
|
||||
```
|
||||
|
||||
- `-x` = extract (entpacken)
|
||||
|
||||
### In bestimmtes Verzeichnis
|
||||
|
||||
```bash
|
||||
tar -xf archiv.tar.gz -C /ziel/verzeichnis
|
||||
```
|
||||
|
||||
### Mit Fortschrittsanzeige
|
||||
|
||||
```bash
|
||||
tar -xvf archiv.tar.gz
|
||||
```
|
||||
|
||||
## Archiv-Inhalt anzeigen
|
||||
|
||||
```bash
|
||||
tar -tf archiv.tar.gz
|
||||
```
|
||||
|
||||
- `-t` = list (auflisten)
|
||||
|
||||
Mit Details:
|
||||
|
||||
```bash
|
||||
tar -tvf archiv.tar.gz
|
||||
```
|
||||
|
||||
## Praktische Beispiele
|
||||
|
||||
### Backup erstellen
|
||||
|
||||
```bash
|
||||
tar -czf backup-$(date +%Y%m%d).tar.gz /home/user/dokumente
|
||||
```
|
||||
|
||||
### Bestimmte Dateien ausschließen
|
||||
|
||||
```bash
|
||||
tar -czf archiv.tar.gz --exclude='*.tmp' --exclude='.git' verzeichnis/
|
||||
```
|
||||
|
||||
### Nur bestimmte Dateien hinzufügen
|
||||
|
||||
```bash
|
||||
tar -czf logs.tar.gz /var/log/*.log
|
||||
```
|
||||
|
||||
### Zu bestehendem Archiv hinzufügen
|
||||
|
||||
```bash
|
||||
tar -rf archiv.tar neue_datei.txt
|
||||
```
|
||||
|
||||
**Hinweis:** Funktioniert nur bei unkomprimierten Archiven!
|
||||
|
||||
### Einzelne Datei aus Archiv extrahieren
|
||||
|
||||
```bash
|
||||
tar -xzf archiv.tar.gz pfad/zur/datei.txt
|
||||
```
|
||||
|
||||
### Archiv auf andere Maschine übertragen
|
||||
|
||||
```bash
|
||||
tar -czf - verzeichnis/ | ssh user@server "cd /ziel && tar -xzf -"
|
||||
```
|
||||
|
||||
## Dateirechte bewahren
|
||||
|
||||
```bash
|
||||
tar -czpf archiv.tar.gz verzeichnis/
|
||||
```
|
||||
|
||||
- `-p` = preserve permissions
|
||||
|
||||
Als Root entpacken und Eigentümer bewahren:
|
||||
|
||||
```bash
|
||||
sudo tar -xpf archiv.tar.gz
|
||||
```
|
||||
|
||||
## Inkrementelles Backup
|
||||
|
||||
```bash
|
||||
tar -czf backup-full.tar.gz -g snapshot.file verzeichnis/
|
||||
tar -czf backup-incr.tar.gz -g snapshot.file verzeichnis/
|
||||
```
|
||||
|
||||
- `-g` = incremental (inkrementell)
|
||||
|
||||
## Geschwindigkeit vs. Kompression
|
||||
|
||||
| Format | Geschwindigkeit | Kompression | Empfehlung |
|
||||
|--------|----------------|-------------|------------|
|
||||
| `.tar` | Sehr schnell | Keine | Lokale Kopien |
|
||||
| `.tar.gz` | Schnell | Gut | Standard |
|
||||
| `.tar.bz2` | Mittel | Besser | Archivierung |
|
||||
| `.tar.xz` | Langsam | Beste | Langzeit-Archiv |
|
||||
|
||||
## Fehler vermeiden
|
||||
|
||||
### Führenden Slash entfernen
|
||||
|
||||
```bash
|
||||
tar -czf archiv.tar.gz --absolute-names /home/user/dokumente # Mit /
|
||||
tar -czf archiv.tar.gz -C /home/user dokumente # Ohne /
|
||||
```
|
||||
|
||||
Zweite Variante ist sicherer beim Entpacken.
|
||||
|
||||
### Große Archive
|
||||
|
||||
Prüfe Speicherplatz vorher:
|
||||
|
||||
```bash
|
||||
du -sh verzeichnis/
|
||||
df -h .
|
||||
```
|
||||
|
||||
### Testen vor Löschen
|
||||
|
||||
```bash
|
||||
tar -czf backup.tar.gz daten/
|
||||
tar -tzf backup.tar.gz | head # Inhalt prüfen
|
||||
# Erst dann löschen:
|
||||
rm -rf daten/
|
||||
```
|
||||
|
||||
## Mit Verschlüsselung
|
||||
|
||||
```bash
|
||||
# Erstellen und verschlüsseln
|
||||
tar -czf - verzeichnis/ | gpg -c > archiv.tar.gz.gpg
|
||||
|
||||
# Entschlüsseln und entpacken
|
||||
gpg -d archiv.tar.gz.gpg | tar -xzf -
|
||||
```
|
||||
|
||||
## Software aus tar.gz installieren
|
||||
|
||||
Eine `.tar.gz`-Datei kann verschiedene Inhalte haben:
|
||||
|
||||
1. **Quellcode** → muss kompiliert werden
|
||||
2. **Kompilierte Binaries** → nur entpacken und ausführen
|
||||
3. **Paket für Distribution** → mit Paketmanager installieren
|
||||
|
||||
### Archiv entpacken und untersuchen
|
||||
|
||||
```bash
|
||||
tar -xvzf paket.tar.gz
|
||||
cd paket
|
||||
ls -la
|
||||
```
|
||||
|
||||
Prüfe immer `README`, `INSTALL` oder `INSTALL.txt`:
|
||||
|
||||
```bash
|
||||
cat README
|
||||
cat INSTALL
|
||||
```
|
||||
|
||||
### Installation aus Quellcode
|
||||
|
||||
**Voraussetzungen installieren:**
|
||||
|
||||
Debian/Ubuntu:
|
||||
```bash
|
||||
sudo apt install build-essential
|
||||
```
|
||||
|
||||
Fedora:
|
||||
```bash
|
||||
sudo dnf groupinstall "Development Tools"
|
||||
```
|
||||
|
||||
**Standard-Kompilierung (autotools):**
|
||||
```bash
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
**CMake-basierte Projekte:**
|
||||
```bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
### Installation von fertigen Binaries
|
||||
|
||||
Wenn das Archiv fertige Programme enthält:
|
||||
|
||||
```bash
|
||||
chmod +x programmname
|
||||
./programmname
|
||||
```
|
||||
|
||||
Permanent installieren nach `/usr/local/bin`:
|
||||
|
||||
```bash
|
||||
sudo cp programmname /usr/local/bin/
|
||||
```
|
||||
|
||||
Oder nach `~/.local/bin` (ohne sudo):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.local/bin
|
||||
cp programmname ~/.local/bin/
|
||||
```
|
||||
|
||||
Stelle sicher, dass `~/.local/bin` im PATH ist:
|
||||
|
||||
```bash
|
||||
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
### Deinstallation
|
||||
|
||||
Bei selbst kompilierten Programmen:
|
||||
|
||||
```bash
|
||||
cd paket/
|
||||
sudo make uninstall
|
||||
```
|
||||
|
||||
Falls `make uninstall` nicht verfügbar ist:
|
||||
|
||||
**Mit checkinstall (empfohlen):**
|
||||
```bash
|
||||
sudo apt install checkinstall # Debian/Ubuntu
|
||||
|
||||
# Statt "sudo make install"
|
||||
sudo checkinstall
|
||||
|
||||
# Später deinstallieren wie normales Paket
|
||||
sudo apt remove paketname
|
||||
```
|
||||
|
||||
**Manuell:**
|
||||
```bash
|
||||
# Liste der installierten Dateien erstellen
|
||||
sudo make install > install.log 2>&1
|
||||
|
||||
# Zum Deinstallieren Dateien aus log löschen
|
||||
```
|
||||
|
||||
### Beispiel-Workflow
|
||||
|
||||
```bash
|
||||
# 1. Entpacken
|
||||
tar -xzf programm-1.0.tar.gz
|
||||
cd programm-1.0
|
||||
|
||||
# 2. Dokumentation lesen
|
||||
cat README
|
||||
cat INSTALL
|
||||
|
||||
# 3. Konfigurieren und kompilieren
|
||||
./configure --prefix=/usr/local
|
||||
make
|
||||
|
||||
# 4. Optional: Tests ausführen
|
||||
make check
|
||||
|
||||
# 5. Installieren
|
||||
sudo make install
|
||||
|
||||
# 6. Testen
|
||||
which programmname
|
||||
programmname --version
|
||||
```
|
||||
|
||||
### Typische Verzeichnisse
|
||||
|
||||
Nach `make install` werden Dateien meist hier installiert:
|
||||
|
||||
- `/usr/local/bin/` - Programme
|
||||
- `/usr/local/lib/` - Bibliotheken
|
||||
- `/usr/local/share/` - Daten/Dokumentation
|
||||
- `/usr/local/etc/` - Konfiguration
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[rsync]] - Alternative für Backups
|
||||
- [[find]] - Dateien für Archivierung finden
|
||||
- [[grep]] - Archiv-Inhalte durchsuchen
|
||||
- [[Dateiberechtigungen]] - Rechte in Archiven bewahren
|
||||
- [[ls]] - Archive anzeigen
|
||||
@@ -0,0 +1,243 @@
|
||||
## Grundlegendes Vorgehen
|
||||
|
||||
Ein BASH Skript, das Argumente verarbeitet und weiterleitet, folgt diesem Muster:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Standardwerte definieren
|
||||
DEFAULT_VALUE="standard"
|
||||
VERBOSE=false
|
||||
TARGET_SCRIPT="./target-script.sh"
|
||||
|
||||
# Argumente parsen
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-v|--verbose)
|
||||
VERBOSE=true
|
||||
shift
|
||||
;;
|
||||
-f|--file)
|
||||
FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-o|--output)
|
||||
OUTPUT="${2:-$DEFAULT_VALUE}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
# Unbekannte Argumente sammeln
|
||||
UNKNOWN_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Alle Argumente an Zielskript weiterleiten
|
||||
"$TARGET_SCRIPT" "${UNKNOWN_ARGS[@]}"
|
||||
```
|
||||
|
||||
## Verschiedene Weiterleitungsstrategien
|
||||
|
||||
### 1. Alle Argumente 1:1 weiterleiten
|
||||
```bash
|
||||
#!/bin/bash
|
||||
./target-script.sh "$@"
|
||||
```
|
||||
|
||||
### 2. Selektive Weiterleitung
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Lokale Verarbeitung
|
||||
WRAPPER_OPTION=""
|
||||
TARGET_ARGS=()
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--wrapper-only)
|
||||
WRAPPER_OPTION="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
TARGET_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Nur relevante Argumente weiterleiten
|
||||
./target-script.sh "${TARGET_ARGS[@]}"
|
||||
```
|
||||
|
||||
### 3. Argumente transformieren
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
TRANSFORMED_ARGS=()
|
||||
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--old-format)
|
||||
TRANSFORMED_ARGS+=("--new-format")
|
||||
;;
|
||||
*)
|
||||
TRANSFORMED_ARGS+=("$arg")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
./target-script.sh "${TRANSFORMED_ARGS[@]}"
|
||||
```
|
||||
|
||||
## Erweiterte Techniken
|
||||
|
||||
### Standardwerte und Validierung
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Standardwerte
|
||||
CONFIG_FILE="${CONFIG_FILE:-/etc/default/myapp}"
|
||||
LOG_LEVEL="${LOG_LEVEL:-INFO}"
|
||||
DRY_RUN=false
|
||||
|
||||
# Hilfsfunktion
|
||||
show_help() {
|
||||
cat << EOF
|
||||
Usage: $0 [OPTIONS] -- [TARGET_ARGS]
|
||||
|
||||
OPTIONS:
|
||||
-c, --config FILE Konfigurationsdatei (default: $CONFIG_FILE)
|
||||
-l, --log-level LVL Log Level (default: $LOG_LEVEL)
|
||||
-n, --dry-run Nur Simulation
|
||||
-h, --help Diese Hilfe
|
||||
|
||||
Alle Argumente nach -- werden an das Zielskript weitergegeben.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Parsing mit -- Separator
|
||||
TARGET_ARGS=()
|
||||
PARSE_TARGET=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
if [[ "$PARSE_TARGET" == true ]]; then
|
||||
TARGET_ARGS+=("$1")
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
-c|--config)
|
||||
CONFIG_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-l|--log-level)
|
||||
LOG_LEVEL="$2"
|
||||
shift 2
|
||||
;;
|
||||
-n|--dry-run)
|
||||
DRY_RUN=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
--)
|
||||
PARSE_TARGET=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unbekannte Option: $1" >&2
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validierung
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "Konfigurationsdatei nicht gefunden: $CONFIG_FILE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ausführung
|
||||
if [[ "$DRY_RUN" == true ]]; then
|
||||
echo "DRY RUN: ./target-script.sh ${TARGET_ARGS[*]}"
|
||||
else
|
||||
./target-script.sh "${TARGET_ARGS[@]}"
|
||||
fi
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Sichere Argumentbehandlung
|
||||
```bash
|
||||
# Verwende Arrays für Argumente
|
||||
ARGS=()
|
||||
while IFS= read -r -d '' arg; do
|
||||
ARGS+=("$arg")
|
||||
done < <(printf '%s\0' "$@")
|
||||
|
||||
# Sichere Weiterleitung
|
||||
./target-script.sh "${ARGS[@]}"
|
||||
```
|
||||
|
||||
### 2. Logging und Debugging
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
DEBUG=${DEBUG:-false}
|
||||
|
||||
debug_log() {
|
||||
if [[ "$DEBUG" == true ]]; then
|
||||
echo "DEBUG: $*" >&2
|
||||
fi
|
||||
}
|
||||
|
||||
debug_log "Received arguments: $*"
|
||||
debug_log "Passing to target: ${TARGET_ARGS[*]}"
|
||||
```
|
||||
|
||||
### 3. Fehlerbehandlung
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail # Strict mode
|
||||
|
||||
# Trap für Cleanup
|
||||
cleanup() {
|
||||
debug_log "Cleaning up..."
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Prüfe ob Zielskript existiert
|
||||
if [[ ! -x "$TARGET_SCRIPT" ]]; then
|
||||
echo "Fehler: Zielskript '$TARGET_SCRIPT' nicht gefunden oder nicht ausführbar" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Führe aus und fange Exit-Code ab
|
||||
if "$TARGET_SCRIPT" "$@"; then
|
||||
debug_log "Zielskript erfolgreich ausgeführt"
|
||||
else
|
||||
exit_code=$?
|
||||
echo "Zielskript fehlgeschlagen mit Exit-Code: $exit_code" >&2
|
||||
exit $exit_code
|
||||
fi
|
||||
```
|
||||
|
||||
## Verwandte Konzepte
|
||||
|
||||
- [[Shell Scripting Best Practices]]
|
||||
- [[BASH Argument Parsing]]
|
||||
- [[Environment Variables in Shell Scripts]]
|
||||
|
||||
---
|
||||
|
||||
**Tags**: #bash #scripting #arguments #shell #automation
|
||||
@@ -0,0 +1,132 @@
|
||||
## Grundlegende Methoden
|
||||
|
||||
### 1. Einfache Variante mit `$0`
|
||||
```bash
|
||||
#!/bin/bash
|
||||
SCRIPT_PATH="$0"
|
||||
echo "Skript wurde aufgerufen als: $SCRIPT_PATH"
|
||||
```
|
||||
|
||||
### 2. Absoluter Pfad des Skripts
|
||||
```bash
|
||||
#!/bin/bash
|
||||
SCRIPT_PATH="$(realpath "$0")"
|
||||
echo "Absoluter Pfad des Skripts: $SCRIPT_PATH"
|
||||
```
|
||||
|
||||
### 3. Verzeichnis des Skripts ermitteln
|
||||
```bash
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
echo "Skript-Verzeichnis: $SCRIPT_DIR"
|
||||
```
|
||||
|
||||
## Robuste Lösung für alle Szenarien
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Funktion zur sicheren Ermittlung des Skript-Pfads
|
||||
get_script_path() {
|
||||
local source="${BASH_SOURCE[0]}"
|
||||
|
||||
# Auflösung von Symlinks
|
||||
while [ -h "$source" ]; do
|
||||
local dir="$(cd -P "$(dirname "$source")" && pwd)"
|
||||
source="$(readlink "$source")"
|
||||
[[ $source != /* ]] && source="$dir/$source"
|
||||
done
|
||||
|
||||
echo "$(cd -P "$(dirname "$source")" && pwd)"
|
||||
}
|
||||
|
||||
SCRIPT_DIR="$(get_script_path)"
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
SCRIPT_FULL_PATH="$SCRIPT_DIR/$SCRIPT_NAME"
|
||||
|
||||
echo "Skript-Verzeichnis: $SCRIPT_DIR"
|
||||
echo "Skript-Name: $SCRIPT_NAME"
|
||||
echo "Vollständiger Pfad: $SCRIPT_FULL_PATH"
|
||||
```
|
||||
|
||||
## Häufige Anwendungsfälle
|
||||
|
||||
### Relative Pfade vom Skript-Verzeichnis aus
|
||||
```bash
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
|
||||
# Zugriff auf andere Dateien relativ zum Skript
|
||||
CONFIG_FILE="$SCRIPT_DIR/config.conf"
|
||||
LOG_DIR="$SCRIPT_DIR/logs"
|
||||
|
||||
# Prüfen ob Konfigurationsdatei existiert
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
echo "Konfiguration gefunden: $CONFIG_FILE"
|
||||
fi
|
||||
```
|
||||
|
||||
### Einbindung anderer Skripts
|
||||
```bash
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
|
||||
# Andere Skripts aus dem gleichen Verzeichnis einbinden
|
||||
source "$SCRIPT_DIR/common_functions.sh"
|
||||
source "$SCRIPT_DIR/config.sh"
|
||||
```
|
||||
|
||||
## Wichtige Unterschiede der Variablen
|
||||
|
||||
| Variable | Beschreibung | Beispiel |
|
||||
|----------|--------------|----------|
|
||||
| `$0` | Aufruf-Name des Skripts | `./script.sh` oder `/path/script.sh` |
|
||||
| `${BASH_SOURCE[0]}` | Tatsächlicher Pfad (auch bei sourcing) | `/absolute/path/script.sh` |
|
||||
| `$(dirname "$0")` | Verzeichnis des Aufrufs | `.` oder `/path` |
|
||||
| `$(realpath "$0")` | Absoluter, aufgelöster Pfad | `/absolute/path/script.sh` |
|
||||
|
||||
## Besondere Situationen
|
||||
|
||||
### Bei gesourcten Skripts
|
||||
```bash
|
||||
# In gesourcten Skripts sollten Sie BASH_SOURCE verwenden
|
||||
SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
|
||||
```
|
||||
|
||||
### Bei Symlinks
|
||||
```bash
|
||||
# Auflösung von Symlinks
|
||||
SCRIPT_PATH="$(readlink -f "$0")"
|
||||
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
|
||||
```
|
||||
|
||||
## Praktisches Beispiel
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# setup.sh - Installationsskript
|
||||
|
||||
# Ermittlung des Skript-Verzeichnisses
|
||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
|
||||
echo "Starte Installation..."
|
||||
echo "Skript-Verzeichnis: $SCRIPT_DIR"
|
||||
echo "Projekt-Root: $PROJECT_ROOT"
|
||||
|
||||
# Installation von Abhängigkeiten
|
||||
pip install -r "$PROJECT_ROOT/requirements.txt"
|
||||
|
||||
# Kopieren von Konfigurationsdateien
|
||||
cp "$SCRIPT_DIR/templates/config.ini" "$PROJECT_ROOT/config/"
|
||||
|
||||
echo "Installation abgeschlossen!"
|
||||
```
|
||||
|
||||
## Tags
|
||||
#bash #scripting #pfade #entwicklung
|
||||
|
||||
## Verwandte Themen
|
||||
- [[BASH Grundlagen]]
|
||||
- [[Dateisystem Navigation]]
|
||||
- [[Skript Entwicklung Best Practices]]
|
||||
@@ -0,0 +1,407 @@
|
||||
Diese Anleitung führt dich praxisnah durch die wichtigsten Bootloader unter Linux – **GRUB 2** (am weitesten verbreitet) und **systemd-boot** – und zeigt, wie du Menüeinträge ausblendest, die **Timeout-Zeit** änderst, den **Standard-Eintrag** festlegst, **Kernel-Parameter** setzt, Themes nutzt u. v. m. Am Ende findest du auch Tipps für UEFI-Bootreihenfolge, Dual-Boot und Fehlerbehebung.
|
||||
|
||||
---
|
||||
|
||||
## 1) Welchen Bootloader habe ich – BIOS/UEFI?
|
||||
|
||||
```bash
|
||||
# UEFI oder BIOS?
|
||||
[ -d /sys/firmware/efi ] && echo "UEFI" || echo "BIOS/Legacy"
|
||||
|
||||
# GRUB oder systemd-boot?
|
||||
bootctl status 2>/dev/null | grep -q 'systemd-boot' && echo "systemd-boot" || echo "GRUB (sehr wahrscheinlich)"
|
||||
```
|
||||
|
||||
- **GRUB 2**: Standard bei Ubuntu, Debian, Fedora, openSUSE, Arch (sofern nicht umgestellt).
|
||||
|
||||
- **systemd-boot**: Häufig bei minimalistischen Setups (Arch, Fedora/Silverblue, Pop!_OS, Manjaro-Varianten) – nur im UEFI-Modus.
|
||||
|
||||
|
||||
> **Wichtig:** **Bearbeite nie direkt** die generierte Datei `/boot/grub/grub.cfg`. Änderungen gehören in `/etc/default/grub` (GRUB) bzw. `/boot/loader/loader.conf` + `…/entries/*.conf` (systemd-boot), und **danach** wird die Konfiguration neu generiert.
|
||||
|
||||
---
|
||||
|
||||
## 2) GRUB 2 konfigurieren (die häufigste Variante)
|
||||
|
||||
### 2.1 Ort der Einstellungen
|
||||
|
||||
- Hauptdatei: `/etc/default/grub`
|
||||
|
||||
- Menüeinträge (automatisch generiert): `/boot/grub/grub.cfg`
|
||||
|
||||
- Regenerieren:
|
||||
|
||||
- Debian/Ubuntu: `sudo update-grub`
|
||||
|
||||
- Fedora/RHEL/openSUSE:
|
||||
|
||||
- BIOS: `sudo grub2-mkconfig -o /boot/grub2/grub.cfg`
|
||||
|
||||
- UEFI: `sudo grub2-mkconfig -o /boot/efi/EFI/<distro>/grub.cfg`
|
||||
|
||||
- Arch: `sudo grub-mkconfig -o /boot/grub/grub.cfg`
|
||||
|
||||
|
||||
> Tipp: Mach vor Änderungen ein Backup:
|
||||
> `sudo cp /etc/default/grub /etc/default/grub.bak.$(date +%F)`
|
||||
|
||||
### 2.2 Zeit bis zur automatischen Auswahl (Timeout)
|
||||
|
||||
In `/etc/default/grub` anpassen:
|
||||
|
||||
```ini
|
||||
GRUB_TIMEOUT=2 # Sekunden bis Autostart
|
||||
GRUB_TIMEOUT_STYLE=menu # "hidden" blendet das Menü aus (siehe unten)
|
||||
```
|
||||
|
||||
- **Menü ausblenden**:
|
||||
|
||||
```ini
|
||||
GRUB_TIMEOUT_STYLE=hidden
|
||||
GRUB_TIMEOUT=0
|
||||
```
|
||||
|
||||
-> System bootet sofort, Menü erscheint **nur** wenn du beim Einschalten **Shift (BIOS)** oder **Esc (UEFI)** gedrückt hältst (je nach Firmware/Distro).
|
||||
|
||||
- **Menü immer zeigen**:
|
||||
|
||||
```ini
|
||||
GRUB_TIMEOUT_STYLE=menu
|
||||
GRUB_TIMEOUT=5
|
||||
```
|
||||
|
||||
|
||||
Danach Konfiguration neu generieren (siehe 2.1).
|
||||
|
||||
### 2.3 Standard-Eintrag festlegen
|
||||
|
||||
Variante A – fester Index (0-basierend, **ändert sich bei Kernel-Updates ggf.**):
|
||||
|
||||
```ini
|
||||
GRUB_DEFAULT=0
|
||||
```
|
||||
|
||||
Variante B – per Name (stabiler):
|
||||
|
||||
```ini
|
||||
GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.10.5"
|
||||
```
|
||||
|
||||
Variante C – „zuletzt gebooteten“ Eintrag merken:
|
||||
|
||||
```ini
|
||||
GRUB_DEFAULT=saved
|
||||
GRUB_SAVEDEFAULT=true
|
||||
```
|
||||
|
||||
Einmalig einen anderen Eintrag für den **nächsten** Boot setzen:
|
||||
|
||||
```bash
|
||||
sudo grub-reboot "Ubuntu, with Linux 6.10.5"
|
||||
# oder nach Index:
|
||||
sudo grub-reboot 2
|
||||
```
|
||||
|
||||
### 2.4 Kernel-Parameter setzen (leiser, schneller, NVIDIA, etc.)
|
||||
|
||||
In `/etc/default/grub`:
|
||||
|
||||
```ini
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
|
||||
GRUB_CMDLINE_LINUX="resume=UUID=<swap-uuid> mitigations=auto"
|
||||
```
|
||||
|
||||
Häufige Parameter:
|
||||
|
||||
- `quiet splash` – leiser Boot mit Grafiksplash (Plymouth).
|
||||
|
||||
- `nomodeset` – Notfall bei Grafiktreibern.
|
||||
|
||||
- `nowatchdog` – schaltet Watchdogs aus (Debug/Workarounds).
|
||||
|
||||
- `acpi_osi=` / `acpi_backlight=` – Backlight-Probleme bei Laptops.
|
||||
|
||||
- `amd_pstate=active` / `intel_pstate=` – CPU-Scaling steuern.
|
||||
|
||||
- `mitigations=off` (nur Test!) – Sicherheits-Mitigations deaktivieren.
|
||||
|
||||
|
||||
> Nach Änderung immer Konfiguration regenerieren (2.1).
|
||||
|
||||
### 2.5 Einträge ausblenden / aufräumen
|
||||
|
||||
- **Andere OS suchen (Dual-Boot)** wird teils aus Sicherheitsgründen deaktiviert. Falls Windows fehlt:
|
||||
|
||||
```ini
|
||||
GRUB_DISABLE_OS_PROBER=false
|
||||
```
|
||||
|
||||
Danach:
|
||||
|
||||
```bash
|
||||
sudo update-grub # bzw. grub2-mkconfig ...
|
||||
```
|
||||
|
||||
- Bestimmte **Recovery-Einträge** ausblenden: In vielen Distros via Paket `grub-customizer` oder durch eigene Skripte unter `/etc/grub.d/` (fortgeschritten).
|
||||
Minimal: Notfalls Einträge in `/etc/grub.d/40_custom` definieren und Standardliste ausblenden (nicht empfohlen, weil Updates überschreiben können).
|
||||
|
||||
|
||||
### 2.6 Themes, Auflösung und Optik
|
||||
|
||||
In `/etc/default/grub`:
|
||||
|
||||
```ini
|
||||
GRUB_GFXMODE=1920x1080
|
||||
GRUB_GFXPAYLOAD_LINUX=keep
|
||||
GRUB_THEME="/boot/grub/themes/mein-theme/theme.txt"
|
||||
```
|
||||
|
||||
- Auflösung prüfen: In der GRUB-Konsole `videoinfo` eintippen (interaktiv).
|
||||
|
||||
- Themes bekommst du aus Paketquellen (z. B. `grub-theme-*`) oder GitHub. Theme in `/boot/grub/themes/...` ablegen.
|
||||
|
||||
|
||||
### 2.7 Sonderfälle (UEFI-Pfad, BIOS, LUKS, Btrfs)
|
||||
|
||||
- **UEFI**: Achte beim `grub2-mkconfig` auf den richtigen **Ausgabepfad** (siehe 2.1).
|
||||
|
||||
- **Vollverschlüsselt (LUKS)**: Kernel-Parameter und initramfs müssen passen (meist automatisch korrekt).
|
||||
|
||||
- **Btrfs-Snapshots** (z. B. mit Snapper): Paket **grub-btrfs** integriert Snapshots ins Menü.
|
||||
|
||||
- **Sichere Bootreihenfolge**: Siehe Abschnitt 4 (efibootmgr).
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 3) systemd-boot konfigurieren (UEFI-Only, sehr schlank)
|
||||
|
||||
### 3.1 Dateien & Struktur
|
||||
|
||||
- Hauptdatei: `/boot/loader/loader.conf`
|
||||
|
||||
- Einträge: `/boot/loader/entries/*.conf` (eine Datei pro Eintrag)
|
||||
|
||||
- Kernel/Initrd liegen meist unter `/boot` oder `/efi`.
|
||||
|
||||
|
||||
### 3.2 Menü ausblenden, Timeout, Standard
|
||||
|
||||
`/boot/loader/loader.conf`:
|
||||
|
||||
```ini
|
||||
timeout 2 # Sekunden (0 = sofort)
|
||||
default arch # oder: @saved
|
||||
editor no # verhindert Bearbeiten im Menü
|
||||
console-mode auto # Grafikmodus: auto, 0..4
|
||||
```
|
||||
|
||||
- **Menü ausblenden**: `timeout 0`
|
||||
-> Menü erscheint bei **gedrückter Leertaste** oder wenn mehrere Einträge vorhanden sind (je nach Firmware/Distribution).
|
||||
|
||||
- **Zuletzt gebooteten Eintrag merken**: `default @saved`
|
||||
Beim Booten auswählen; systemd-boot speichert die Wahl in `loader/`.
|
||||
|
||||
|
||||
### 3.3 Einträge bearbeiten
|
||||
|
||||
Beispiel `/boot/loader/entries/arch.conf`:
|
||||
|
||||
```ini
|
||||
title Arch Linux
|
||||
linux /vmlinuz-linux
|
||||
initrd /initramfs-linux.img
|
||||
options root=UUID=<root-uuid> rw quiet splash
|
||||
```
|
||||
|
||||
- **Kernel-Parameter** hängst du einfach an `options` an.
|
||||
|
||||
- Mehrere `initrd` Zeilen sind erlaubt (z. B. Microcode + initramfs).
|
||||
|
||||
|
||||
### 3.4 Kernel installieren/aktualisieren
|
||||
|
||||
- Viele Distros nutzen `kernel-install` Hooks, die automatisch passende `entries/*.conf` erzeugen.
|
||||
|
||||
- Ansonsten Einträge manuell pflegen (simpel und transparent).
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 4) UEFI-Bootreihenfolge & Dual-Boot
|
||||
|
||||
### 4.1 Bootreihenfolge mit `efibootmgr`
|
||||
|
||||
Liste anzeigen:
|
||||
|
||||
```bash
|
||||
sudo efibootmgr
|
||||
```
|
||||
|
||||
Reihenfolge setzen (Beispiel, IDs anpassen):
|
||||
|
||||
```bash
|
||||
sudo efibootmgr -o 0003,0001,0002
|
||||
```
|
||||
|
||||
**GRUB** oder **systemd-boot** sollte ganz vorn stehen.
|
||||
Ein einzelnes Boot-Target (z. B. Windows) **einmalig** booten:
|
||||
|
||||
```bash
|
||||
sudo efibootmgr -n 0002
|
||||
```
|
||||
|
||||
### 4.2 Windows fehlt im Menü?
|
||||
|
||||
- Bei **GRUB**: `GRUB_DISABLE_OS_PROBER=false` (siehe 2.5) und neu generieren.
|
||||
|
||||
- Bei **systemd-boot**: eigenen `windows.conf` Eintrag unter `entries/` anlegen oder die automatische Erkennung der Distribution nutzen.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 5) Häufige Aufgaben – Schritt-für-Schritt
|
||||
|
||||
### A) Menü ausblenden & Sofort-Boot (GRUB)
|
||||
|
||||
1. `sudo nano /etc/default/grub`
|
||||
|
||||
2. Setze:
|
||||
|
||||
```ini
|
||||
GRUB_TIMEOUT_STYLE=hidden
|
||||
GRUB_TIMEOUT=0
|
||||
```
|
||||
|
||||
3. `sudo update-grub` (oder passendes `grub*-mkconfig`)
|
||||
|
||||
4. Test: Reboot, ggf. **Shift/Esc** halten, um das Menü zu zeigen.
|
||||
|
||||
|
||||
### B) Timeout auf 5 s und Standard-Kernel merken (GRUB)
|
||||
|
||||
1. `/etc/default/grub`:
|
||||
|
||||
```ini
|
||||
GRUB_TIMEOUT_STYLE=menu
|
||||
GRUB_TIMEOUT=5
|
||||
GRUB_DEFAULT=saved
|
||||
GRUB_SAVEDEFAULT=true
|
||||
```
|
||||
|
||||
2. Regenerieren.
|
||||
|
||||
3. Nächster Boot merkt sich deine Auswahl automatisch.
|
||||
|
||||
|
||||
### C) Ruhiger, schneller Boot mit Splash (GRUB)
|
||||
|
||||
1. `/etc/default/grub`:
|
||||
|
||||
```ini
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
|
||||
```
|
||||
|
||||
2. Optional Plymouth-Theme installieren.
|
||||
|
||||
3. Regenerieren und neu starten.
|
||||
|
||||
|
||||
### D) systemd-boot: Menü 1 s, zuletzt Gebootetes merken
|
||||
|
||||
1. `sudoedit /boot/loader/loader.conf`:
|
||||
|
||||
```ini
|
||||
timeout 1
|
||||
default @saved
|
||||
editor no
|
||||
```
|
||||
|
||||
2. Reboot, Auswahl wird gemerkt.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 6) Sicherheit, Recovery & Wartung
|
||||
|
||||
- **Secure Boot**: Mit GRUB in der Regel via `shim` signiert – bei eigenen Kernel/Modulen ggf. MOK-Signatur nötig. systemd-boot lädt nur signierte Images, wenn Secure Boot aktiv ist.
|
||||
|
||||
- **Recovery-Pfad**: Halte mindestens einen **nicht-minimalen** Kernel-Eintrag ohne aggressive Parameter bereit (ohne `nomodeset`, ohne `mitigations=off` etc.).
|
||||
|
||||
- **Backups**: Sichere `/etc/default/grub`, `loader.conf` und eigene `entries/*.conf`.
|
||||
|
||||
- **Fallback-Boot**: Notiere einen **UEFI-One-Shot** Befehl (`efibootmgr -n <ID>`), falls das Menü einmal nicht erscheint.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 7) Troubleshooting (schnelle Checks)
|
||||
|
||||
- GRUB-Menü erscheint nicht:
|
||||
|
||||
- Firmware zeigt direkt Windows → Reihenfolge mit `efibootmgr` korrigieren.
|
||||
|
||||
- `GRUB_TIMEOUT_STYLE=hidden`? → Temporär **Shift/Esc** beim Start.
|
||||
|
||||
- Neue Kernel erscheinen nicht:
|
||||
|
||||
- Nach Updates `update-grub` / `grub*-mkconfig` ausgeführt?
|
||||
|
||||
- Pfad für UEFI-Ausgabe korrekt?
|
||||
|
||||
- Dual-Boot-Einträge fehlen:
|
||||
|
||||
- `os-prober` aktivieren (`GRUB_DISABLE_OS_PROBER=false`), dann neu generieren.
|
||||
|
||||
- Schwarzer Bildschirm nach Grafiktreiber-Wechsel:
|
||||
|
||||
- Temporär `nomodeset` im Bootmenü ergänzen (e), dann dauerhaft in `GRUB_CMDLINE_LINUX_DEFAULT`.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 8) Nützliche Befehle (Cheatsheet)
|
||||
|
||||
```bash
|
||||
# GRUB neu generieren (Debian/Ubuntu)
|
||||
sudo update-grub
|
||||
|
||||
# GRUB neu generieren (UEFI, Fedora-Beispiel)
|
||||
sudo grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
|
||||
|
||||
# Standard-Eintrag nur für den nächsten Boot (GRUB)
|
||||
sudo grub-reboot 2
|
||||
sudo grub-reboot "Advanced options for Ubuntu>Ubuntu, with Linux 6.10.5"
|
||||
|
||||
# Zuletzt gebooteten Eintrag merken (Konfig siehe oben)
|
||||
# -> einfach normal auswählen; GRUB speichert es.
|
||||
|
||||
# systemd-boot Status
|
||||
bootctl status
|
||||
|
||||
# UEFI Boots verwalten
|
||||
sudo efibootmgr
|
||||
sudo efibootmgr -o 0003,0001,0002
|
||||
sudo efibootmgr -n 0002 # One-shot
|
||||
|
||||
# Welche Auflösungen unterstützt GRUB?
|
||||
# (in GRUB-Konsole: drücke 'c', dann)
|
||||
videoinfo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9) Empfehlung nach Use-Case
|
||||
|
||||
- **Einsteiger / klassische Desktop-Distro** → **GRUB 2** beibehalten, Timeout 2–5 s, `saved`-Default, `quiet splash`.
|
||||
|
||||
- **Schlanke, transparente Setups (UEFI)** → **systemd-boot**: `timeout 1`, `default @saved`.
|
||||
|
||||
- **Dual-Boot mit Windows** → GRUB 2 + `os-prober` aktivieren; in UEFI die Reihenfolge mit `efibootmgr` sichern.
|
||||
|
||||
- **Schneller „kioskartiger“ Boot** → Menü verstecken (`hidden/0` bzw. `timeout 0`) und Hotkey kennen (Shift/Esc/Leertaste).
|
||||
|
||||
|
||||
---
|
||||
|
||||
Wenn du mir deine Distribution und dein Ziel (z. B. „Menü vollständig verstecken“, „Windows hinzufügen“, „Splash aktivieren“) nennst, schreibe ich dir die **exakten** Befehle für dein System in einem kleinen, kopierfertigen Block.
|
||||
@@ -0,0 +1,85 @@
|
||||
Alles klar 👍 – hier eine **allgemeine Schritt-für-Schritt-Anleitung**, wie du unter [[Linux]] mit `dd` einen **bootfähigen USB-Stick aus _beliebigen_ ISO-Dateien** erstellst:
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Bootfähigen USB-Stick mit `dd` erstellen
|
||||
|
||||
### 1. ISO-Datei bereitlegen
|
||||
|
||||
Speichere die ISO-Datei in einem bekannten Pfad, z. B.:
|
||||
|
||||
```
|
||||
~/Downloads/dein.iso
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. USB-Stick einstecken und Gerät identifizieren
|
||||
|
||||
Liste alle Laufwerke:
|
||||
|
||||
```bash
|
||||
lsblk
|
||||
```
|
||||
|
||||
oder
|
||||
|
||||
```bash
|
||||
sudo fdisk -l
|
||||
```
|
||||
|
||||
Beispielausgabe:
|
||||
|
||||
```
|
||||
sda 500G # deine interne Festplatte
|
||||
sdb 16G # dein USB-Stick
|
||||
```
|
||||
|
||||
👉 Der Stick ist hier `/dev/sdb`.
|
||||
⚠️ Wichtig: **Niemals eine Partition (z. B. `/dev/sdb1`) wählen, immer das ganze Gerät (`/dev/sdb`).**
|
||||
|
||||
---
|
||||
|
||||
### 3. ISO auf den Stick schreiben
|
||||
|
||||
Ersetze die Platzhalter:
|
||||
|
||||
```bash
|
||||
sudo dd if=/pfad/zur/datei.iso of=/dev/sdX bs=4M status=progress oflag=sync
|
||||
```
|
||||
|
||||
- `if=` → Pfad zur ISO-Datei (z. B. `~/Downloads/dein.iso`)
|
||||
|
||||
- `of=` → dein USB-Gerät (z. B. `/dev/sdb`)
|
||||
|
||||
- `bs=4M` → Blockgröße, sorgt für schnelleres Schreiben
|
||||
|
||||
- `status=progress` → zeigt den Fortschritt
|
||||
|
||||
- `oflag=sync` → sorgt für sauberes Schreiben
|
||||
|
||||
|
||||
**Beispiel:**
|
||||
|
||||
```bash
|
||||
sudo dd if=~/Downloads/bazzite.iso of=/dev/sdb bs=4M status=progress oflag=sync
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Schreibvorgang abschließen
|
||||
|
||||
Bevor du den Stick abziehst:
|
||||
|
||||
```bash
|
||||
sync
|
||||
sudo eject /dev/sdb
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Stick zum Booten nutzen
|
||||
|
||||
Jetzt kannst du den Stick in den Zielrechner stecken, im BIOS/UEFI den Stick auswählen und davon booten.
|
||||
|
||||
---
|
||||
@@ -0,0 +1,76 @@
|
||||
How can I disable the [[kvm]] Kernel in [[Linux]], so that I can launch a virtual machine in VirtualBox
|
||||
|
||||
---
|
||||
When you run [[VirtualBox]] on a Linux host, it can conflict with the **KVM kernel modules** (`kvm` and `kvm_intel` or `kvm_amd`). VirtualBox doesn’t use KVM, and if those modules are loaded, they can prevent VirtualBox VMs from starting properly.
|
||||
|
||||
To disable KVM, you can either **temporarily unload** the modules or **permanently blacklist** them.
|
||||
|
||||
---
|
||||
|
||||
### 🔹 Option 1: Temporarily Disable KVM
|
||||
|
||||
Run the following commands (with root privileges):
|
||||
|
||||
```bash
|
||||
sudo modprobe -r kvm_intel
|
||||
sudo modprobe -r kvm_amd
|
||||
sudo modprobe -r kvm
|
||||
```
|
||||
|
||||
- If your CPU is Intel, unload `kvm_intel`.
|
||||
|
||||
- If your CPU is AMD, unload `kvm_amd`.
|
||||
|
||||
- Then unload the generic `kvm` module.
|
||||
|
||||
|
||||
This will disable KVM until the next reboot.
|
||||
|
||||
---
|
||||
|
||||
### 🔹 Option 2: Permanently Disable KVM
|
||||
|
||||
To prevent KVM from loading on boot, blacklist the modules:
|
||||
|
||||
1. Create a blacklist file:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/modprobe.d/blacklist-kvm.conf
|
||||
```
|
||||
|
||||
2. Add these lines:
|
||||
|
||||
```
|
||||
blacklist kvm
|
||||
blacklist kvm_intel
|
||||
blacklist kvm_amd
|
||||
```
|
||||
|
||||
3. Save and exit.
|
||||
|
||||
4. Update initramfs (on some distros, required):
|
||||
|
||||
```bash
|
||||
sudo update-initramfs -u
|
||||
```
|
||||
|
||||
5. Reboot your system.
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 🔹 Verify
|
||||
|
||||
After reboot (or unloading), check that no KVM modules are loaded:
|
||||
|
||||
```bash
|
||||
lsmod | grep kvm
|
||||
```
|
||||
|
||||
If the output is empty, KVM is disabled and VirtualBox should work.
|
||||
|
||||
---
|
||||
|
||||
⚠️ **Note:** If you ever want to use QEMU/KVM again, you’ll need to remove those blacklist entries and reboot.
|
||||
|
||||
Would you like me to also show you how to make VirtualBox auto-unload KVM just when you launch a VM (without disabling it system-wide)? That way, you can keep using both VirtualBox and KVM on the same system.
|
||||
@@ -0,0 +1,418 @@
|
||||
Hier ist ein umfassendes Shell-Skript für die Installation von DisplayLink-Treibern unter Linux:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# DisplayLink Driver Installation Script for Linux
|
||||
# Author: Assistant
|
||||
# Version: 1.0
|
||||
# Date: $(date +%Y-%m-%d)
|
||||
|
||||
set -e
|
||||
|
||||
# Farben für Output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging
|
||||
LOG_FILE="/var/log/displaylink-install.log"
|
||||
exec > >(tee -a "$LOG_FILE")
|
||||
exec 2>&1
|
||||
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
echo -e "${BLUE} DisplayLink Driver Installation Script${NC}"
|
||||
echo -e "${BLUE}========================================${NC}"
|
||||
|
||||
# Funktionen
|
||||
log() {
|
||||
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1${NC}"
|
||||
}
|
||||
|
||||
warn() {
|
||||
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
|
||||
}
|
||||
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
error "Dieses Skript muss als root ausgeführt werden!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
detect_distro() {
|
||||
if [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
DISTRO=$ID
|
||||
VERSION=$VERSION_ID
|
||||
log "Distribution erkannt: $PRETTY_NAME"
|
||||
else
|
||||
error "Distribution konnte nicht erkannt werden"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install_dependencies() {
|
||||
log "Installiere benötigte Abhängigkeiten..."
|
||||
|
||||
case $DISTRO in
|
||||
ubuntu|debian)
|
||||
apt update
|
||||
apt install -y wget curl unzip dkms build-essential \
|
||||
linux-headers-$(uname -r) git libdrm-dev \
|
||||
x11-xserver-utils mesa-utils
|
||||
;;
|
||||
fedora|centos|rhel)
|
||||
if command -v dnf &> /dev/null; then
|
||||
dnf install -y wget curl unzip dkms gcc make \
|
||||
kernel-devel-$(uname -r) git libdrm-devel \
|
||||
xrandr mesa-utils
|
||||
else
|
||||
yum install -y wget curl unzip dkms gcc make \
|
||||
kernel-devel-$(uname -r) git libdrm-devel \
|
||||
xrandr mesa-utils
|
||||
fi
|
||||
;;
|
||||
opensuse*)
|
||||
zypper install -y wget curl unzip dkms gcc make \
|
||||
kernel-default-devel git libdrm-devel \
|
||||
xrandr Mesa-utils
|
||||
;;
|
||||
arch|manjaro)
|
||||
pacman -Sy --noconfirm wget curl unzip dkms base-devel \
|
||||
linux-headers git libdrm xorg-xrandr mesa-utils
|
||||
;;
|
||||
*)
|
||||
warn "Unbekannte Distribution. Versuche generische Installation..."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
download_displaylink_driver() {
|
||||
log "Lade neueste DisplayLink-Treiber herunter..."
|
||||
|
||||
# Erstelle temporäres Verzeichnis
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
cd "$TEMP_DIR"
|
||||
|
||||
# DisplayLink Download URL (Ubuntu 22.04 kompatibel)
|
||||
DRIVER_VERSION="5.8.0-63.33"
|
||||
DRIVER_URL="https://www.synaptics.com/sites/default/files/Ubuntu/pool/stable/main/all/synaptics-repository-keyring.deb"
|
||||
|
||||
# Alternative: Verwende evdi Repository
|
||||
log "Installiere EVDI (Extensible Virtual Display Interface)..."
|
||||
git clone https://github.com/DisplayLink/evdi.git
|
||||
cd evdi
|
||||
make && make install
|
||||
cd ..
|
||||
|
||||
# Offizieller DisplayLink Treiber Download
|
||||
OFFICIAL_URL="https://www.synaptics.com/sites/default/files/Ubuntu/pool/stable/main/all/"
|
||||
|
||||
# Neueste verfügbare Version ermitteln
|
||||
log "Ermittle neueste verfügbare Treiberversion..."
|
||||
|
||||
# Fallback: Direkte Installation über Repository
|
||||
case $DISTRO in
|
||||
ubuntu|debian)
|
||||
# Füge DisplayLink Repository hinzu
|
||||
wget -O - https://www.synaptics.com/sites/default/files/Ubuntu/displaylink-debian-ubuntu-signing-key.pub | apt-key add -
|
||||
echo "deb https://www.synaptics.com/sites/default/files/Ubuntu/ $(lsb_release -cs) stable" > /etc/apt/sources.list.d/displaylink.list
|
||||
apt update
|
||||
apt install -y displaylink-driver
|
||||
;;
|
||||
*)
|
||||
# Manuelle Installation für andere Distributionen
|
||||
DRIVER_FILE="displaylink-driver-5.8.0-63.33.zip"
|
||||
log "Lade $DRIVER_FILE herunter..."
|
||||
|
||||
# Beispiel-Download (URL muss aktualisiert werden)
|
||||
if ! wget -q --spider "https://www.displaylink.com/downloads/file?id=1768"; then
|
||||
warn "Automatischer Download fehlgeschlagen. Manuelle Installation erforderlich."
|
||||
log "Bitte laden Sie den neuesten Treiber von https://www.displaylink.com/downloads/ubuntu herunter"
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_displaylink_driver() {
|
||||
log "Installiere DisplayLink-Treiber..."
|
||||
|
||||
# Stoppe potentiell laufende Services
|
||||
systemctl stop dlm.service 2>/dev/null || true
|
||||
systemctl stop displaylink-driver.service 2>/dev/null || true
|
||||
|
||||
case $DISTRO in
|
||||
ubuntu|debian)
|
||||
# Bereits über Repository installiert
|
||||
log "Treiber über Repository installiert"
|
||||
;;
|
||||
*)
|
||||
# Manuelle Installation
|
||||
if [ -f "displaylink-driver-*.run" ] || [ -f "DisplayLink*.run" ]; then
|
||||
chmod +x DisplayLink*.run 2>/dev/null || chmod +x displaylink-driver-*.run
|
||||
./DisplayLink*.run --noexec --target displaylink-driver 2>/dev/null || ./displaylink-driver-*.run --noexec --target displaylink-driver
|
||||
cd displaylink-driver
|
||||
./displaylink-installer.sh install
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# EVDI Modul laden
|
||||
modprobe evdi || warn "EVDI Modul konnte nicht geladen werden"
|
||||
}
|
||||
|
||||
configure_services() {
|
||||
log "Konfiguriere SystemD Services..."
|
||||
|
||||
# DisplayLink Service aktivieren
|
||||
systemctl enable dlm.service 2>/dev/null || systemctl enable displaylink-driver.service 2>/dev/null || true
|
||||
|
||||
# Erstelle Custom Service falls nötig
|
||||
if [ ! -f "/etc/systemd/system/displaylink.service" ]; then
|
||||
cat > /etc/systemd/system/displaylink.service << EOF
|
||||
[Unit]
|
||||
Description=DisplayLink Manager Service
|
||||
After=display-manager.service
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStartPre=/sbin/modprobe evdi
|
||||
ExecStart=/opt/displaylink/DisplayLinkManager
|
||||
ExecStop=/opt/displaylink/DisplayLinkManager --stop
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=graphical.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable displaylink.service
|
||||
fi
|
||||
}
|
||||
|
||||
fix_common_issues() {
|
||||
log "Behebe bekannte Probleme..."
|
||||
|
||||
# Problem 1: EVDI Modul beim Boot laden
|
||||
if ! grep -q "evdi" /etc/modules; then
|
||||
echo "evdi" >> /etc/modules
|
||||
log "EVDI zu /etc/modules hinzugefügt"
|
||||
fi
|
||||
|
||||
# Problem 2: Xorg Konfiguration
|
||||
mkdir -p /etc/X11/xorg.conf.d/
|
||||
cat > /etc/X11/xorg.conf.d/20-displaylink.conf << EOF
|
||||
Section "OutputClass"
|
||||
Identifier "DisplayLink"
|
||||
MatchDriver "evdi"
|
||||
Driver "modesetting"
|
||||
Option "AccelMethod" "none"
|
||||
EndSection
|
||||
EOF
|
||||
|
||||
# Problem 3: Udev Regeln
|
||||
cat > /etc/udev/rules.d/99-displaylink.rules << EOF
|
||||
# DisplayLink USB devices
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", TAG+="systemd", ENV{SYSTEMD_WANTS}="displaylink.service"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="*", RUN+="/bin/systemctl start displaylink.service"
|
||||
EOF
|
||||
|
||||
udevadm control --reload-rules
|
||||
|
||||
# Problem 4: Permissions
|
||||
usermod -a -G plugdev $SUDO_USER 2>/dev/null || true
|
||||
|
||||
# Problem 5: Wayland Kompatibilität (für GNOME)
|
||||
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
|
||||
warn "Wayland erkannt. DisplayLink funktioniert besser mit X11."
|
||||
log "Erstelle GDM Custom Config für X11..."
|
||||
|
||||
mkdir -p /etc/gdm3
|
||||
cat > /etc/gdm3/custom.conf << EOF
|
||||
[daemon]
|
||||
WaylandEnable=false
|
||||
DefaultSession=gnome-xorg
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
check_installation() {
|
||||
log "Überprüfe Installation..."
|
||||
|
||||
# Service Status
|
||||
if systemctl is-active --quiet dlm.service || systemctl is-active --quiet displaylink-driver.service || systemctl is-active --quiet displaylink.service; then
|
||||
log "DisplayLink Service läuft erfolgreich"
|
||||
else
|
||||
warn "DisplayLink Service läuft nicht. Starte Service..."
|
||||
systemctl start displaylink.service 2>/dev/null || systemctl start dlm.service 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Modul Status
|
||||
if lsmod | grep -q evdi; then
|
||||
log "EVDI Kernel Modul erfolgreich geladen"
|
||||
else
|
||||
warn "EVDI Kernel Modul nicht geladen. Versuche manuelles Laden..."
|
||||
modprobe evdi || error "EVDI Modul konnte nicht geladen werden"
|
||||
fi
|
||||
|
||||
# USB Geräte check
|
||||
if lsusb | grep -i displaylink; then
|
||||
log "DisplayLink USB-Gerät erkannt"
|
||||
else
|
||||
warn "Kein DisplayLink USB-Gerät erkannt. Schließen Sie ein Gerät an."
|
||||
fi
|
||||
}
|
||||
|
||||
create_troubleshooting_script() {
|
||||
log "Erstelle Troubleshooting-Skript..."
|
||||
|
||||
cat > /usr/local/bin/displaylink-troubleshoot << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
echo "=== DisplayLink Troubleshooting ==="
|
||||
echo ""
|
||||
|
||||
echo "1. Service Status:"
|
||||
systemctl status displaylink.service dlm.service displaylink-driver.service 2>/dev/null || echo "Services nicht gefunden"
|
||||
echo ""
|
||||
|
||||
echo "2. Kernel Module:"
|
||||
lsmod | grep evdi || echo "EVDI Modul nicht geladen"
|
||||
echo ""
|
||||
|
||||
echo "3. USB Devices:"
|
||||
lsusb | grep -i displaylink || echo "Keine DisplayLink Geräte gefunden"
|
||||
echo ""
|
||||
|
||||
echo "4. Displays:"
|
||||
xrandr --listproviders 2>/dev/null || echo "Xrandr nicht verfügbar"
|
||||
echo ""
|
||||
|
||||
echo "5. Logs:"
|
||||
journalctl -u displaylink.service --no-pager -n 10 2>/dev/null || echo "Keine Service Logs"
|
||||
echo ""
|
||||
|
||||
echo "=== Schnelle Fixes ==="
|
||||
echo "Service neu starten:"
|
||||
echo " sudo systemctl restart displaylink.service"
|
||||
echo ""
|
||||
echo "Modul neu laden:"
|
||||
echo " sudo modprobe -r evdi && sudo modprobe evdi"
|
||||
echo ""
|
||||
echo "Display erkennung:"
|
||||
echo " xrandr --setprovideroutputsource 1 0 && xrandr --auto"
|
||||
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/bin/displaylink-troubleshoot
|
||||
log "Troubleshooting-Skript erstellt: /usr/local/bin/displaylink-troubleshoot"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
log "Räume temporäre Dateien auf..."
|
||||
cd /
|
||||
rm -rf "$TEMP_DIR" 2>/dev/null || true
|
||||
}
|
||||
|
||||
main() {
|
||||
log "Starte DisplayLink Installation..."
|
||||
|
||||
check_root
|
||||
detect_distro
|
||||
install_dependencies
|
||||
download_displaylink_driver
|
||||
install_displaylink_driver
|
||||
configure_services
|
||||
fix_common_issues
|
||||
check_installation
|
||||
create_troubleshooting_script
|
||||
cleanup
|
||||
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Installation abgeschlossen!${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo ""
|
||||
log "Installation erfolgreich abgeschlossen!"
|
||||
log "Bitte starten Sie das System neu für beste Ergebnisse."
|
||||
log "Bei Problemen verwenden Sie: displaylink-troubleshoot"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Nächste Schritte:${NC}"
|
||||
echo "1. System neu starten"
|
||||
echo "2. DisplayLink Gerät anschließen"
|
||||
echo "3. Monitor-Konfiguration mit: xrandr --auto"
|
||||
echo "4. Bei Problemen: displaylink-troubleshoot ausführen"
|
||||
}
|
||||
|
||||
# Trap für Cleanup
|
||||
trap cleanup EXIT
|
||||
|
||||
# Hauptfunktion ausführen
|
||||
main "$@"
|
||||
```
|
||||
|
||||
## Zusätzliche Konfigurationsdateien
|
||||
|
||||
### 1. Desktop-Shortcut für schnelle Display-Konfiguration:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Erstelle Desktop-Shortcut
|
||||
cat > ~/Desktop/configure-displays.desktop << EOF
|
||||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Type=Application
|
||||
Name=Configure DisplayLink Displays
|
||||
Comment=Configure external displays via DisplayLink
|
||||
Exec=bash -c 'xrandr --setprovideroutputsource 1 0 && xrandr --auto && notify-send "Displays konfiguriert"'
|
||||
Icon=preferences-desktop-display
|
||||
Terminal=false
|
||||
Categories=System;Settings;
|
||||
EOF
|
||||
|
||||
chmod +x ~/Desktop/configure-displays.desktop
|
||||
```
|
||||
|
||||
### 2. Automatische Display-Konfiguration bei USB-Anschluss:
|
||||
|
||||
```bash
|
||||
# Udev-Regel für automatische Konfiguration
|
||||
cat > /etc/udev/rules.d/99-displaylink-autoconfig.rules << EOF
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", RUN+="/usr/local/bin/displaylink-autoconfig.sh"
|
||||
EOF
|
||||
|
||||
# Autoconfig-Skript
|
||||
cat > /usr/local/bin/displaylink-autoconfig.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
sleep 3
|
||||
export DISPLAY=:0
|
||||
xrandr --setprovideroutputsource 1 0
|
||||
xrandr --auto
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/bin/displaylink-autoconfig.sh
|
||||
```
|
||||
|
||||
## Verwendung:
|
||||
|
||||
1. Skript als root ausführen:
|
||||
```bash
|
||||
sudo bash displaylink-install.sh
|
||||
```
|
||||
|
||||
2. Nach der Installation System neu starten
|
||||
|
||||
3. Bei Problemen Troubleshooting ausführen:
|
||||
```bash
|
||||
displaylink-troubleshoot
|
||||
```
|
||||
|
||||
Das Skript automatisiert die komplette Installation und behebt die häufigsten Probleme mit DisplayLink-Treibern unter verschiedenen Linux-Distributionen.
|
||||
@@ -0,0 +1,140 @@
|
||||
Kurz gesagt: **Nein – GNU Stow führt keine Skripte aus.**
|
||||
Und das ist auch Absicht 🙂
|
||||
|
||||
GNU Stow macht **nur eine Sache**:
|
||||
|
||||
> Es erzeugt und entfernt Symlinks.
|
||||
|
||||
Keine Hooks.
|
||||
Keine Post-Deploy-Skripte.
|
||||
Keine Automatik.
|
||||
|
||||
---
|
||||
|
||||
# 🧠 Warum ist das so?
|
||||
|
||||
Stow ist bewusst:
|
||||
|
||||
* minimalistisch
|
||||
* deterministisch
|
||||
* side-effect-frei
|
||||
|
||||
Dadurch bleibt dein Setup transparent und reproduzierbar.
|
||||
|
||||
---
|
||||
|
||||
# ✅ Aber: Man kann es kombinieren
|
||||
|
||||
Wenn du beim „Deploy“ zusätzlich Dinge tun willst (z. B. Monitor-Symlink setzen, Pakete installieren, Cache leeren, etc.), gibt es saubere Lösungen:
|
||||
|
||||
---
|
||||
|
||||
# 🔹 Lösung 1: Bootstrap-Script (empfohlen)
|
||||
|
||||
Du schreibst dir ein Script wie:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
cd ~/dotfiles
|
||||
|
||||
echo "→ Stowing configs"
|
||||
stow hypr
|
||||
stow waybar
|
||||
stow zsh
|
||||
|
||||
echo "→ Setting monitor config"
|
||||
ln -sf desktop.conf hypr/.config/hypr/monitors/current.conf
|
||||
|
||||
echo "→ Reloading Hyprland"
|
||||
hyprctl reload
|
||||
```
|
||||
|
||||
Dann einfach:
|
||||
|
||||
```bash
|
||||
./install.sh
|
||||
```
|
||||
|
||||
💡 Das ist die professionellste Lösung.
|
||||
|
||||
---
|
||||
|
||||
# 🔹 Lösung 2: Hostname-basierte Logik im Script
|
||||
|
||||
```bash
|
||||
HOST=$(hostname)
|
||||
|
||||
if [[ "$HOST" == "desktop" ]]; then
|
||||
ln -sf desktop.conf hypr/.config/hypr/monitors/current.conf
|
||||
elif [[ "$HOST" == "laptop" ]]; then
|
||||
ln -sf laptop.conf hypr/.config/hypr/monitors/current.conf
|
||||
fi
|
||||
```
|
||||
|
||||
Dann musst du nichts manuell wählen.
|
||||
|
||||
---
|
||||
|
||||
# 🔹 Lösung 3: Makefile (sehr elegant)
|
||||
|
||||
Beispiel:
|
||||
|
||||
```make
|
||||
install:
|
||||
stow hypr
|
||||
stow waybar
|
||||
./scripts/select-monitor.sh
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```bash
|
||||
make install
|
||||
```
|
||||
|
||||
Sehr beliebt in Dotfile-Repos.
|
||||
|
||||
---
|
||||
|
||||
# 🔹 Lösung 4: „echte“ Dotfile-Manager
|
||||
|
||||
Wenn du wirklich Logik + Templates willst:
|
||||
|
||||
* chezmoi
|
||||
* yadm
|
||||
|
||||
Diese können:
|
||||
|
||||
* Hostname erkennen
|
||||
* Variablen verwenden
|
||||
* Templates generieren
|
||||
* Skripte ausführen
|
||||
|
||||
Aber sie sind komplexer als Stow.
|
||||
|
||||
---
|
||||
|
||||
# 🎯 Empfehlung für dich (Hyprland + mehrere Systeme)
|
||||
|
||||
Da du:
|
||||
|
||||
* Monitor-Configs pro System brauchst
|
||||
* wahrscheinlich Arch nutzt
|
||||
* modular arbeiten willst
|
||||
|
||||
👉 **Stow + Bootstrap-Script** ist die perfekte Balance.
|
||||
|
||||
---
|
||||
|
||||
# 💬 Kurzantwort auf deine Frage
|
||||
|
||||
| Frage | Antwort |
|
||||
| ------------------------ | ----------------- |
|
||||
| Führt Stow Skripte aus? | ❌ Nein |
|
||||
| Kann man es kombinieren? | ✅ Ja |
|
||||
| Beste Praxis? | Stow + install.sh |
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
Für Integration von Programmen ins Startmenü
|
||||
Lege Datei `some_awesome_app.desktop` mit folgendem Inhalt:
|
||||
```bash
|
||||
[Desktop Entry]
|
||||
Name=Name of Application
|
||||
GenericName=Super generic Name
|
||||
Comment=This is an awesome application
|
||||
Exec=/path/to/executable
|
||||
Icon=/path/to/icon
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Categories=Utility;Application;
|
||||
```
|
||||
|
||||
- Für aktuellen Nutzer: `~/.local/share/applications`
|
||||
- Systemweit (`sudo` beim Anlegen nicht vergessen): `/usr/share/applications`
|
||||
## Weitere Felder
|
||||
```bash
|
||||
# ...
|
||||
Encoding=UTF-8
|
||||
Version=1.0
|
||||
StartupWMClass=ExampleApp
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
Ich hab ein bisschen recherchiert und ein paar gute Optionen gefunden — sowohl Open Source / native [[Linux]]-PlugIns als auch Tipps, wie man bewährte Windows/Proprietär-Drum-Libraries unter Linux laufen lassen kann. Wenn du willst, kann ich auch ein paar kommerzielle Kandidaten heraussuchen, die unter Linux getestet sind. Hier zunächst ein Überblick:
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Native bzw. sehr gut unter Linux laufende Drum-Sampler / Drum-PlugIns
|
||||
|
||||
Diese Tools/Plugins laufen nativ unter Linux / oder haben Linux-Versionen, und sind gute Alternativen oder Ergänzungen zu EZ-Drummer:
|
||||
|
||||
| Plugin / Tool | Format / Linux-Support | Vorteile | Einschränkungen / Punkte, auf die man achten sollte |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **[[DrumGizmo]]** | VSTi & LV2 Version, stand-alone auch; multichannel, multilayered. | Sehr gute Drumsounds mit mehreren Velocity-Schichten; man kann einzelne Mikros / Kanäle nutzen, also gute Flexibilität beim Mischen. | Die Drums werden nicht immer sofort so fett wie bei kommerziellen Tools; erfordert gutes Setup (Routing, Mix) und ggf. eigene Kits. |
|
||||
| **[[LinuxSampler]]** | VST, LV2, DSSI etc. | Sehr mächtig, kann große Sample-Libraries nutzen; volle Kontrolle. | Bedienung nicht so „slick“ wie bei Markenprodukten, evtl. Lernkurve; große Sample-Bibliotheken nötig für gute Vielfalt. |
|
||||
| **[[drumkv1]]** | LV2 / Standalone (JACK / ALSA MIDI)-Client; native Linux. | Leichtgewichtig, einfach einzurichten; ideal wenn man nicht so viele Features braucht. | Kein High-End-Drumkit mit riesiger Bibliothek; klingt eher sauber/klassisch, nicht unbedingt super „produziert“. |
|
||||
| **Geonkick** | Synthesizer Drum / Percussion; VST3 und LV2 auf Linux. | Sehr flexibel bei perkussiven Sounds, interessant wenn man eigene, eher synthetische Drums bauen will. | Eher auf Drum-Synthese fokussiert, nicht ein „Drumkit-Sammler“ mit kompletten Kits wie bei EZ Drummer etc. Kann sein, dass man noch eigene Samples oder Bearbeitung braucht, damit’s wirklich gut passt. |
|
||||
| **Sitala** | Stand-alone / PlugIn Version, unterstützt Linux in früheren Versionen (V1) zumindest; sehr leicht zu bedienen. | Schnelle Ergebnisse; ideal für kreative Ideen, wenn man schnell Drums triggern möchte; UI ist simpel und effizient. | Wenn man ganz spezifische Kits oder sehr aufwendige Layer/Velocity braucht, stößt man evtl. an Grenzen; neuere Versionen evtl. eingeschränkter Linux-Support. |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Kommerzielle PlugIns / Windows-Drum-Libraries unter Linux verwenden
|
||||
|
||||
Wenn dir die Qualität / Klang von EZ-Drummer oder ähnlichen wichtig ist und du nicht komplett auf native Alternativen umsteigen willst, hier ein paar Tipps, wie man kommerzielle Plugins unter Linux zuverlässiger nutzen kann:
|
||||
|
||||
- **Wine + VST Bridge / yabridge**: Viele Nutzer berichten, dass Windows-VSTs mit yabridge in Reaper unter Linux ziemlich gut laufen. Manche hatten Probleme mit Soundlibrary-Pfaden etc., aber wenn man das richtig einrichtet (z. B. Wineprefix, korrekter Pfad zu den Samples), dann klappt’s oft sehr gut.
|
||||
- **Reaper Native + Linux-VST Unterstützung**: Die Linux-Version von Reaper kann native Linux VSTs nutzen, und mit yabridge auch Windows VSTs; das heißt, du kannst beides kombinieren.
|
||||
- **Sample Libraries exportieren / konvertieren**: Wenn du z. B. Libraries hast, die in einem Format sind, das EZ-Drummer verwendet, könnte man prüfen, ob man die Samples in ein universelles Format bringt (z.B. SFZ) und dann mit einem Sampler wie LinuxSampler oder DrumGizmo nutzen. Das erspart Abhängigkeiten.
|
||||
|
||||
---
|
||||
|
||||
Wenn du möchtest, kann ich ein paar **kommerziell verfügbare Drum-PlugIns** heraussuchen, die nachweislich unter Linux + Reaper stabil laufen, inkl. Preis & Klangbeispiele, damit du vergleichen kannst? Möchtest du das?
|
||||
@@ -0,0 +1,32 @@
|
||||
Kann ich in einer [[Linux]] Konsole die komplette Eingabe auf einmal löschen? (z.B. wenn man sich beim Blättern durch die Historie oder beim Scuehn mit `STRG-R` "verrannt" hat)?
|
||||
|
||||
---
|
||||
Ja, das geht 😊 – in der Linux-Shell (z. B. Bash, Zsh) kannst du mit **einem Shortcut die ganze Eingabezeile löschen**, ohne Zeichen für Zeichen löschen zu müssen:
|
||||
|
||||
- **`Strg-u`**
|
||||
Löscht den gesamten Text von der aktuellen Cursorposition bis zum Zeilenanfang.
|
||||
Wenn der Cursor am Ende der Zeile steht (Standardfall), verschwindet die ganze Eingabe.
|
||||
|
||||
|
||||
Weitere nützliche "Kill"-Shortcuts in der Bash/Zsh:
|
||||
|
||||
- `Strg-k` → löscht von der Cursorposition bis zum Zeilenende
|
||||
|
||||
- `Strg-w` → löscht das Wort links vom Cursor
|
||||
|
||||
- `Strg-y` → fügt das zuletzt Gelöschte wieder ein (ähnlich "Paste")
|
||||
|
||||
|
||||
Wenn du dich mit **`Strg-r` (Reverse Search)** "verrannt" hast:
|
||||
|
||||
- Einfach **`Strg-g`** drücken → bricht die History-Suche ab und bringt dich zurück in eine leere Eingabezeile.
|
||||
|
||||
|
||||
👉 Falls du wirklich _immer_ eine komplett neue, leere Zeile willst, ist die schnellste Kombination:
|
||||
|
||||
- `Strg-u` (Cursor am Ende) oder
|
||||
|
||||
- `Strg-g` (falls du gerade in einer History-Suche bist).
|
||||
|
||||
|
||||
Willst du, dass ich dir eine kleine Übersicht als "Spickzettel" für Bash/Zsh-Shortcuts schreibe?
|
||||
@@ -0,0 +1,272 @@
|
||||
|
||||
Ich bin auf der Suche nach einer guten Software für meine MP3 Musiksammlung in Linux, mit die Synchronisation mit meinem Android Handy gut funktioniert.
|
||||
|
||||
### Hintergrund
|
||||
Bisher habe ich als Ex-Windows-Nutzer das Programm "Media-Monkey" in der Pro Version verwendet, d.h. auf dem PC und dem Handy mit der gleichnamigen App.
|
||||
|
||||
### Anfrage
|
||||
Bitte zeige mir gute Alternativen, bestehend aus Linux Programm für PC und Android App für Handy.
|
||||
|
||||
### Anforderungen:
|
||||
* Flexible Organisation der Library nach Benutzerdefinierten Kriterien (z.B. Album Artist, Genre, Album, etc.)
|
||||
* Bearbeitungsmöglichkeiten aller Song Infos
|
||||
* Bewertungssystem und Verschlagwortung
|
||||
* Playlisten: statisch und dynamsisch (d.h. regelbasiert)
|
||||
* Leichte Synchronisierbarkeit zwischen Rechner und Handy:
|
||||
* Änderungen an Metadaten, insbes. "Last Played" werden in beide Richtungen übernommen
|
||||
* Möglichkeit die Bitrate der MP3s beim Synchronisieren anzupassen (z.B. um Speicherplatz auf Handy zu sparen)
|
||||
* Synchronisation kabelgebunden oder über WLAN
|
||||
|
||||
### Optionale Anforderungen
|
||||
* Möglichkeit, fehlende Metadaten aus WWW zu ergänzen
|
||||
* Erstellung von Benutzerdefinierten Metadaten Feldern, z.B. als Berechnung aus anderen Feldern
|
||||
---
|
||||
|
||||
---
|
||||
Super, danke für die präzise Beschreibung – das hilft sehr!
|
||||
Ich fasse mal die Landschaft für dich zusammen: es gibt unter Linux kein exaktes 1:1-Pendant zu **MediaMonkey**, aber einige Kombinationen aus Desktop-Software + Android-App können sehr nahe herankommen.
|
||||
|
||||
---
|
||||
|
||||
## 1. **MusicBee (via Wine) + Gonemad / PowerAmp (Android)**
|
||||
|
||||
- **Linux (Wine):** MusicBee läuft recht stabil unter Wine. Viele Ex-MediaMonkey-User nutzen es als Ersatz, weil es die meisten Features (flexible Library, Tags, Bewertungen, Smart-Playlists, Metadaten aus dem Netz) abdeckt.
|
||||
|
||||
- **Android:** Keine eigene App, aber Sync mit **GoneMAD** oder **PowerAmp** möglich. Mit Tools wie `syncthing` oder `Resilio Sync` kannst du Library, Ratings & Playcounts abgleichen.
|
||||
|
||||
- **Pro:** Funktionsumfang fast wie MediaMonkey.
|
||||
|
||||
- **Contra:** Keine native Linux-App, Integration Handy↔PC muss manuell über Sync-Tools eingerichtet werden.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 2. **Clementine / Strawberry (Linux) + Android App Clementine Remote / DSub**
|
||||
|
||||
- **Linux:** [[Strawberry 1]] ist ein Fork von Clementine, moderner gepflegt.
|
||||
|
||||
- Bibliotheksorganisation nach vielen Kriterien.
|
||||
|
||||
- Metadatenbearbeitung, inkl. Coverdownload von Last.fm, MusicBrainz.
|
||||
|
||||
- Playlists: statisch + dynamisch.
|
||||
|
||||
- **Android:** Offizielle Clementine-Remote-App für Steuerung, oder Streaming via Subsonic-kompatibler Apps (z. B. [[DSub]], [[Ultrasonic]]).
|
||||
- siehe auch [[Subsonic-API]]
|
||||
|
||||
- **Sync:**
|
||||
|
||||
- Metadaten (Playcount, Ratings) werden am PC gespeichert.
|
||||
|
||||
- Handy-Sync ist etwas frickelig, echte **bidirektionale Playcount-Synchronisation** gibt es nicht nativ.
|
||||
|
||||
- **Pro:** Native Linux-App, offene Formate.
|
||||
|
||||
- **Contra:** Sync mit Handy nicht so nahtlos wie MediaMonkey.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 3. **Amarok / Elisa (KDE) + Android (KDE Connect, VLC, PowerAmp)**
|
||||
|
||||
- **Linux:** Amarok war früher sehr stark, inzwischen etwas veraltet. Elisa ist der moderne KDE-Player, aber weniger mächtig in Smart-Playlists.
|
||||
|
||||
- **Android:** Mit **KDE Connect** kannst du Dateien kabellos synchronisieren, aber Metadaten-Sync (z. B. "Last Played") fehlt.
|
||||
|
||||
- **Pro:** Schön in KDE integriert.
|
||||
|
||||
- **Contra:** Nicht so mächtig wie MediaMonkey.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 4. **Rhythmbox + Android (Lollypop / VLC)**
|
||||
|
||||
- **Linux:** Rhythmbox (GNOME Standard) oder Lollypop (modernere Oberfläche).
|
||||
|
||||
- **Features:** Library, Metadaten, Bewertungen.
|
||||
|
||||
- **Sync:** Per Kabel (MTP) oder WLAN/Sync-Tools, aber kein sauberer Playcount-Abgleich.
|
||||
|
||||
- **Contra:** Sehr basic, keine regelbasierten Playlists wie MediaMonkey.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 5. **Self-Hosted Server + Android (Subsonic/Airsonic + DSub/Ampache)**
|
||||
|
||||
- **Linux:** Airsonic, [Navidrome] oder Koel als **Musikserver**.
|
||||
|
||||
- **Features:** Vollständige Weboberfläche, flexible Library, Tags, Playcounts, Bewertungen.
|
||||
|
||||
- **Android:** Mit Apps wie **DSub**, **Substreamer**, **Ultrasonic** Zugriff und **automatische Playcount-Sync**.
|
||||
|
||||
- **Pro:**
|
||||
|
||||
- Playcounts, Metadaten und Playlists sind _immer synchronisiert_.
|
||||
|
||||
- Zugriff auch von unterwegs.
|
||||
|
||||
- **Contra:** Kein klassischer "Desktop-Player", sondern Server-Setup. Eher für Power-User.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 6. **Syncthing / rsync als Backend für bestehende Player**
|
||||
|
||||
- Falls dir wichtig ist, die MP3s in voller Struktur 1:1 zwischen Rechner und Handy zu haben (inkl. Playcounts, Bitrate-Anpassung), kannst du auch einen reinen Player wie **Strawberry** am PC + **GoneMAD** oder **PowerAmp** am Handy nutzen, und den Abgleich über **Syncthing** erledigen.
|
||||
|
||||
- Bitraten-Transkodierung beim Sync ist tricky: am besten über ein Script oder mit Tools wie **FFmpeg** beim Kopieren lösen.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Fazit (Empfehlungen)
|
||||
|
||||
- **"Am nächsten an MediaMonkey"** → **MusicBee unter Wine + GoneMAD/PowerAmp auf Android** (aber kein native Linux).
|
||||
|
||||
- **Native Linux-Lösung, solide & gepflegt** → **Strawberry auf Linux + GoneMAD auf Android**, Sync per Syncthing/rsync.
|
||||
|
||||
- **Wenn Playcount/Rating-Sync über Geräte _wirklich_ zentral ist** → **[[Navidrome]] (Server) + DSub/Ultrasonic auf Android**.
|
||||
|
||||
|
||||
---
|
||||
|
||||
👉 Frage an dich:
|
||||
Ist dir wichtiger, dass das Ganze **nativ auf Linux läuft** (also Wine vermeiden), oder dass du **möglichst nahe an der MediaMonkey-Experience bleibst**, auch wenn’s Wine erfordert?
|
||||
|
||||
---
|
||||
Ich ziehe es vor, wenn es nativ unter Linux läuft. Es **muss** nicht auch nicht Media Monkey nachahmen, es sollte vom Funktionsumfang nur ähnlich mächtig sein. Wenn für Synchronisation extra Tools benötigt werden ist das ok. Wichtig wäre mir, dass Bearbeitungen am PC (Hinzugefügte Songs, Playlisten statisch und dynamisch, Metadaten etc) möglichst 1 zu 1 auch auf dem Handy verfügbar sind.
|
||||
|
||||
---
|
||||
Perfekt — danke für die Präzisierung. Du willst also **native Linux**-Werkzeuge, die in Summe ungefähr so mächtig sind wie MediaMonkey, und die Änderungen am PC (neue Songs, statische + dynamische Playlists, Metadaten usw.) sollen **möglichst 1:1 auf dem Android-Handy verfügbar** sein. Ich habe zwei praxiserprobte, native-unter-Linux-Workflows für genau dieses Ziel — einer ist _server-zentriert_ (am zuverlässigsten für Bidirektionalität von Playcounts/Playlists/Metadaten), der andere ist _Datei-Sync/Offline_-orientiert (besser für rein lokale Dateien/Offline-Nutzung, aber mit Einschränkungen bei Playcount/Ratings). Ich liste jeweils Voraussetzungen, wie es funktioniert, Vor-/Nachteile und konkrete Umsetzungspunkte.
|
||||
|
||||
# Empfehlung A — **(Meine Top-Wahl)** Lokaler Musik-Server ([[Navidrome]]/Airsonic) + native Player (Strawberry) auf PC + Subsonic-Client auf Android (z. B. DSub / Ultrasonic)
|
||||
|
||||
**Warum:** [[Navidrome]] (leichtgewichtiger, moderner Subsonic-kompatibler Server) läuft nativ unter Linux, indexiert deine Musikdateien und stellt Bibliothek + Playlists + Playcounts + Ratings zentral zur Verfügung. Android-Clients, die das Subsonic-API unterstützen, können sowohl streamen als auch offline cachen und melden Wiedergaben/Playcounts zurück an den Server — dadurch hast du eine echte 1:1-Synchronisation der Nutzungsdaten zwischen PC und Handy. [Navidrome] bietet außerdem Transcoding/Download-Transkodierung (nützlich, um Bitrate beim Übertragen zu reduzieren). Auf dem Desktop nutzt du einen richtigen Player/Tag-Editor wie **Strawberry** zum Bearbeiten der Dateien; der Server erkennt Änderungen bei Rescan/Auto-Import. ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
Wie das zusammenwirkt — Kurzablauf:
|
||||
|
||||
1. Auf dem Linux-PC: music-folder (z. B. `~/Music`) → Strawberry zum Abspielen & Tag-Editing. Strawberry ist native, hat Smart/Dynamic-Playlists und Tag-Editoren. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
2. Auf dem Linux-PC: [[Navidrome]] (als Dienst oder Docker) so konfigurieren, dass es auf genau denselben Music-Ordner zeigt. [[Navidrome]] indexiert die Dateien, liest Tags, Playlists (importiert `.m3u`) und verwaltet Playcounts/ratings serverseitig. ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
3. Auf Android: Subsonic-kompatible App installieren (z. B. **DSub**, **Ultrasonic** oder Subsonic-App). Diese Apps können streamen, offline cachen/downloaden und (je nach App/Server-Einstellung) Playbacks/Playcounts an [[Navidrome]] zurückmelden; sie unterstützen auch clientseitiges Transcoding / Download-Qualitätssteuerung. (Subsonic-App-Ökosystem ist groß, DSub ist ein verbreiteter Client.) ([subsonic.org](https://www.subsonic.org/pages/apps.jsp?utm_source=chatgpt.com "Subsonic Apps"))
|
||||
|
||||
|
||||
Wesentliche Vorteile:
|
||||
|
||||
- **Echte Bidirektionalität** für Playcount/Play/Rating, wenn Client ↔ Server dies unterstützt (sehr viel zuverlässiger als reine Datei-Syncs). ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
- **On-the-fly Transcoding / Bitrate-Limit** beim Stream/Download — du kannst z. B. mobil immer in 128–192 kbps laden, während der PC die Originals behält. ([[Navidrome]](https://www.Navidrome.org/docs/usage/configuration-options/?utm_source=chatgpt.com "[[Navidrome]] Configuration Options"))
|
||||
|
||||
- Desktop bleibt native (Strawberry), Server läuft nativ unter Linux. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
|
||||
Nachteile / Dinge, die du beachten solltest:
|
||||
|
||||
- Es ist kein „klassischer“ Einzelprogramm-Desktop-Workflow mehr, sondern ein **Server + Clients**-Setup (läuft aber lokal auf deinem Rechner, keine Cloud nötig).
|
||||
|
||||
- Manche Subsonic-Clients handhaben Offline-Caching unterschiedlich (Ordnerstruktur, Caching-Verhalten). Testen lohnt sich. ([GitHub](https://github.com/airsonic-advanced/airsonic-advanced/issues/873?utm_source=chatgpt.com "DSub sync/cache with Airsonic 11 dumps all files into main ..."))
|
||||
|
||||
|
||||
**Kurz-Setup-Hinweise:**
|
||||
|
||||
- Installiere [[Navidrome]] (Deb/Flatpak/Docker) und stelle `MUSIC_FOLDER` auf deinen bestehenden Musikordner. Aktiviere ggf. `AutoImportPlaylists`. ([[Navidrome]](https://www.Navidrome.org/docs/usage/configuration-options/?utm_source=chatgpt.com "[[Navidrome]] Configuration Options"))
|
||||
|
||||
- Installiere Strawberry als Desktop-Player und bearbeite Tags/Playlists dort; [[Navidrome]] neu scannen lassen oder Auto-Rescan aktivieren. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
- Auf Android: DSub/Ultrasonic konfigurieren (Server-URL mit deiner lokalen IP), in der App die Download/Transcode-Qualität setzen. ([subsonic.org](https://www.subsonic.org/pages/apps.jsp?utm_source=chatgpt.com "Subsonic Apps"))
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Empfehlung B — **Datei-Sync (offline) Workflow**: Strawberry (Linux) + Syncthing (oder rsync) + Android-Player (GoneMAD / Poweramp)
|
||||
|
||||
**Warum:** Wenn du viel offline hörst und tatsächliche Dateien auf dem Handy brauchst (z. B. Hi-Res oder bestimmte Ordnerstruktur), ist Syncthing eine sehr komfortable, native Lösung zum Spiegeln von Ordnern PC ↔ Handy. Strawberry bearbeitet Tags/Playlists auf dem PC und die Dateien werden 1:1 auf's Handy kopiert. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
Wie das zusammenwirkt — Kurzablauf:
|
||||
|
||||
1. Strawberry verwaltet die Dateien lokal und erzeugt Playlists (M3U).
|
||||
|
||||
2. Syncthing synchronisiert den Music-Ordner (und Playlist-Exports) automatisch auf das Handy. Syncthing läuft nativ unter Linux und Android. ([Gist](https://gist.github.com/johanwiden/d14ec414bd212e2ee8c2fae576115ef7?utm_source=chatgpt.com "How to configure Syncthing for Android"))
|
||||
|
||||
3. Auf Android: ein mächtiger Offline-Player wie **GoneMAD** oder **Poweramp** liest die Dateien/Playlists vom synchronisierten Ordner.
|
||||
|
||||
|
||||
Vorteile:
|
||||
|
||||
- Volle Offline-Verfügbarkeit (keine Server-Software nötig).
|
||||
|
||||
- Absolute Dateiintegrität — exakt die gleichen MP3/FLAC liegen auf beiden Geräten.
|
||||
|
||||
|
||||
Wesentliche Einschränkungen (sehr wichtig):
|
||||
|
||||
- **Playcounts / Ratings**: Viele Android-Player (z. B. Poweramp) speichern Playcounts/Rating in einer **internen App-Datenbank** und schreiben diese **nicht** zuverlässig zurück in die MP3-Tags (POPM/PCNT). Dadurch geht die echte bidirektionale Synchronisation von „Last played / playcount / rating“ verloren, bzw. sie ist nur mit zusätzlichen Tools/Workarounds möglich. Poweramp z.B. unterstützt POPM nicht als schreibbaren Standard-Rating-Export. GoneMAD hat einige Optionen, kann aber nicht immer sauber bidirektional zu jedem Desktop-Tool synchronisieren. ([Poweramp](https://forum.powerampapp.com/topic/21099-will-not-recognize-ratings-tags/?utm_source=chatgpt.com "Will not recognize ratings tags - Poweramp Feature Requests"))
|
||||
|
||||
- Android-Medienindexer kann neue Dateien verzögert erkennen; manchmal muss man den Index anstoßen oder die App neu starten, wenn Syncthing neue Musik ablegt. ([Syncthing Community Forum](https://forum.syncthing.net/t/music-synced-onto-phone-not-picked-up-by-android/22191?utm_source=chatgpt.com "Music Synced onto Phone Not Picked Up by Android"))
|
||||
|
||||
|
||||
Workarounds:
|
||||
|
||||
- Verwende ID3-Frames, die als Standard existieren — z. B. **PCNT** (Play Counter) oder **POPM** (Popularimeter) — und scripte gelegentlich ein Update/Export/Import dieser Frames zwischen Player-DB und Dateien. Die PCNT-Frame ist Teil der ID3-Spec und kann playcount direkt in die Datei schreiben — das funktioniert aber nur, wenn der Android-Player diese Frames auch schreibt/liest. ([id3.org](https://id3.org/id3v2.3.0?utm_source=chatgpt.com "id3v2.3.0"))
|
||||
|
||||
- Manche Nutzer verwenden periodische Exporte (z. B. M3U/CSV) und ein kleines Script, das die DB-Werte abgleicht — ist aber Aufwand und fragile Lösung. (Wenn du experimentierfreudig bist, möglich.)
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Vergleich & Entscheidungshilfe — kurz
|
||||
|
||||
- **Wenn du wirklich möchtest, dass Playcounts / LastPlayed / Ratings verlässlich zwischen PC ↔ Handy synchron sind → wähle den Server-Ansatz ([[Navidrome]] / Airsonic)**. Das ist die sauberste, wartungsarme Lösung für bidirektionale Nutzungsdaten; zusätzlich hast du komfortable Transcoding-Optionen für mobile Daten/Storage. ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
- **Wenn du maximale Offline-Kontrolle über die Dateien willst (keine Serverstruktur) → wähle Syncthing + ein mächtiges Android-Player,** akzeptiere aber Einschränkungen bei Ratings/Playcounts bzw. plane zusätzliche Scripts/Workarounds ein. ([Gist](https://gist.github.com/johanwiden/d14ec414bd212e2ee8c2fae576115ef7?utm_source=chatgpt.com "How to configure Syncthing for Android"))
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Konkrete Vorschläge zum sofortigen Ausprobieren (in dieser Reihenfolge)
|
||||
|
||||
1. **Testlauf Server-Option (empfohlen):**
|
||||
|
||||
- Installiere [[Navidrome]] (Docker oder Paket) und zeige es auf `~/Music`. ([[Navidrome]] ist leicht, kann lokal laufen.) ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
- Installiere DSub (oder Ultrasonic) auf dem Handy, verbinde mit [[Navidrome]]. Teste Streaming + Offline-Download + setzte Download-Bitrate auf z. B. 160 kbps. ([subsonic.org](https://www.subsonic.org/pages/apps.jsp?utm_source=chatgpt.com "Subsonic Apps"))
|
||||
|
||||
- Auf dem PC: installiere **Strawberry**, bearbeite ein paar Tags & Playlists, lasse [[Navidrome]] neu scannen — prüfe die Änderungen im Android-Client. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
2. **Falls du stattdessen Offline-Dateien bevorzugst:**
|
||||
|
||||
- Installiere **Syncthing** auf PC + Android, sync einen kleinen Test-Musikordner. ([Gist](https://gist.github.com/johanwiden/d14ec414bd212e2ee8c2fae576115ef7?utm_source=chatgpt.com "How to configure Syncthing for Android"))
|
||||
|
||||
- Auf Android: teste **GoneMAD** (sehr anpassbar) oder **Poweramp** als Player, probiere, ob Ratings/Playcounts in deiner Kombination zuverlässig geschrieben/gezogen werden (Hinweis: Poweramp schreibt POPM nicht). ([Google Play](https://play.google.com/store/apps/details?hl=en_US&id=gonemad.gmmp&utm_source=chatgpt.com "GoneMAD Music Player - Apps on Google Play"))
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Quellen (wichtigste Belege)
|
||||
|
||||
- Strawberry — native Linux Player: Smart/dynamic playlists, Tag-Editor, MusicBrainz/cover lookup. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
- [[Navidrome]] — leichter Subsonic-kompatibler Server, lokal nutzbar; Optionen für AutoImportPlaylists / Transcoding/Download-Transcode. ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
- Subsonic/DSub ecosystem — Android-Clients für Subsonic/[[Navidrome]] (Streaming, Offline Caching, Bitrate/Transcode Optionen). ([subsonic.org](https://www.subsonic.org/pages/apps.jsp?utm_source=chatgpt.com "Subsonic Apps"))
|
||||
|
||||
- ID3-Frames (PCNT / POPM) — Playcount-Frame `PCNT` ist Teil der ID3v2-Spec (kann in Datei gespeichert werden). ([id3.org](https://id3.org/id3v2.3.0?utm_source=chatgpt.com "id3v2.3.0"))
|
||||
|
||||
- Poweramp & Rating/Tagging Limit: Poweramp schreibt/liest POPM/PCNT nicht standardmäßig; Ratings werden intern gespeichert — wichtige Einschränkung für Datei-Sync Workflows. ([Poweramp](https://forum.powerampapp.com/topic/21099-will-not-recognize-ratings-tags/?utm_source=chatgpt.com "Will not recognize ratings tags - Poweramp Feature Requests"))
|
||||
|
||||
- Syncthing für Datei-Sync Android ↔ PC — verbreitete Praxis, aber Android-Indexing / Rechte / folder ownership sind zu beachten. ([Gist](https://gist.github.com/johanwiden/d14ec414bd212e2ee8c2fae576115ef7?utm_source=chatgpt.com "How to configure Syncthing for Android"))
|
||||
|
||||
|
||||
---
|
||||
|
||||
Wenn du willst, mache ich sofort eines von beiden für dich praktisch:
|
||||
|
||||
- **Variante A:** Ich erstelle dir eine Schritt-für-Schritt-Anleitung (konkret für Debian/Ubuntu/Fedora) zum Installieren/Einrichten von [[Navidrome]] + Strawberry + DSub (inkl. Beispiel-Config für Transcoding/AutoImport).
|
||||
|
||||
- **Variante B:** Oder ich schreibe ein kurzes Syncthing-Setup-Tutorial + Hinweise, wie du Ratings/Playcounts am besten per ID3/Script synchronisierst (inkl. Beispielscript, das `PCNT`/`POPM` per `mutagen` oder `eyeD3` setzt).
|
||||
|
||||
|
||||
Sag mir einfach welches Setup du zuerst ausprobieren willst — ich liefere die konkrete, sofort ausführbare Anleitung (inkl. Konfig-Snippets).
|
||||
@@ -0,0 +1,34 @@
|
||||
Is there a keyboard shortcut on linux to open a terminal
|
||||
|
||||
---
|
||||
Yes 👍 — most Linux desktop environments (DEs) have a default keyboard shortcut for opening a terminal, but it can vary depending on which one you’re using:
|
||||
|
||||
- **GNOME (Ubuntu, Fedora, Debian, etc.):**
|
||||
`Ctrl + Alt + T`
|
||||
|
||||
- **KDE Plasma (Kubuntu, openSUSE, etc.):**
|
||||
Usually also `Ctrl + Alt + T` (but can be customized).
|
||||
|
||||
- **XFCE (Xubuntu, etc.):**
|
||||
Often `Ctrl + Alt + T`, or you can set your own in _Settings → Keyboard → Application Shortcuts_.
|
||||
|
||||
- **Others (MATE, Cinnamon, LXQt, etc.):**
|
||||
Many also use `Ctrl + Alt + T` by default.
|
||||
|
||||
|
||||
If it doesn’t work, you can always **assign your own shortcut**:
|
||||
|
||||
1. Go to your system’s **Keyboard Settings**.
|
||||
|
||||
2. Find **Custom Shortcuts** (or _Keyboard Shortcuts_).
|
||||
|
||||
3. Add a new one:
|
||||
|
||||
- Command: `gnome-terminal` (or `konsole`, `xfce4-terminal`, depending on your DE).
|
||||
|
||||
- Shortcut: choose something like `Ctrl + Alt + T`.
|
||||
|
||||
|
||||
---
|
||||
|
||||
👉 Which desktop environment or Linux distro are you using? I can give you the exact steps for your setup.
|
||||
@@ -0,0 +1,15 @@
|
||||
[[Linux Musikprogramme]]
|
||||
[[Softlinks 1]]
|
||||
[[Synchronisation & Backup 1]]
|
||||
|
||||
# Konsolen Know-How
|
||||
[[Linux Konsole Zeichen löschen]]
|
||||
[[Paketinstallation aus tar.gz]]
|
||||
[[Disable KVM for VirtualBox]]
|
||||
[[Linux Terminal Shortcut]]
|
||||
[[Drives & Mounts 1]]
|
||||
[[Computerkram/find]]
|
||||
[[Link-Verknüpfung in Linux]]
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
* [[ssh Key erstellen]]
|
||||
* [[mein fstab]]
|
||||
*
|
||||
@@ -0,0 +1,142 @@
|
||||
|
||||
|
||||
|
||||
|
||||
**Warum:** [[Navidrome]] (leichtgewichtiger, moderner Subsonic-kompatibler Server, -> [[Subsonic-API]]) läuft nativ unter Linux, indexiert deine Musikdateien und stellt Bibliothek + Playlists + Playcounts + Ratings zentral zur Verfügung. Android-Clients, die das Subsonic-API unterstützen, können sowohl streamen als auch offline cachen und melden Wiedergaben/Playcounts zurück an den Server — dadurch hast du eine echte 1:1-Synchronisation der Nutzungsdaten zwischen PC und Handy. [Navidrome] bietet außerdem Transcoding/Download-Transkodierung (nützlich, um Bitrate beim Übertragen zu reduzieren). Auf dem Desktop nutzt du einen richtigen Player/Tag-Editor wie [[Strawberry 1]] zum Bearbeiten der Dateien; der Server erkennt Änderungen bei Rescan/Auto-Import. ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
Wie das zusammenwirkt — Kurzablauf:
|
||||
|
||||
1. Auf dem Linux-PC: music-folder (z. B. `~/Music`) → Strawberry zum Abspielen & Tag-Editing. Strawberry ist native, hat Smart/Dynamic-Playlists und Tag-Editoren. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
2. Auf dem Linux-PC: [[Navidrome]] (als Dienst oder Docker) so konfigurieren, dass es auf genau denselben Music-Ordner zeigt. [[Navidrome]] indexiert die Dateien, liest Tags, Playlists (importiert `.m3u`) und verwaltet Playcounts/ratings serverseitig. ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
3. Auf Android: Subsonic-kompatible App installieren (z. B. **DSub**, **Ultrasonic** oder Subsonic-App). Diese Apps können streamen, offline cachen/downloaden und (je nach App/Server-Einstellung) Playbacks/Playcounts an [[Navidrome]] zurückmelden; sie unterstützen auch clientseitiges Transcoding / Download-Qualitätssteuerung. (Subsonic-App-Ökosystem ist groß, DSub ist ein verbreiteter Client.) ([subsonic.org](https://www.subsonic.org/pages/apps.jsp?utm_source=chatgpt.com "Subsonic Apps"))
|
||||
|
||||
|
||||
Wesentliche Vorteile:
|
||||
|
||||
- **Echte Bidirektionalität** für Playcount/Play/Rating, wenn Client ↔ Server dies unterstützt (sehr viel zuverlässiger als reine Datei-Syncs). ([[Navidrome]](https://www.Navidrome.org/docs/overview/?utm_source=chatgpt.com "[[Navidrome]] Overview"))
|
||||
|
||||
- **On-the-fly Transcoding / Bitrate-Limit** beim Stream/Download — du kannst z. B. mobil immer in 128–192 kbps laden, während der PC die Originals behält. ([[Navidrome]](https://www.Navidrome.org/docs/usage/configuration-options/?utm_source=chatgpt.com "[[Navidrome]] Configuration Options"))
|
||||
|
||||
- Desktop bleibt native (Strawberry), Server läuft nativ unter Linux. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
|
||||
Nachteile / Dinge, die du beachten solltest:
|
||||
|
||||
- Es ist kein „klassischer“ Einzelprogramm-Desktop-Workflow mehr, sondern ein **Server + Clients**-Setup (läuft aber lokal auf deinem Rechner, keine Cloud nötig).
|
||||
|
||||
- Manche Subsonic-Clients handhaben Offline-Caching unterschiedlich (Ordnerstruktur, Caching-Verhalten). Testen lohnt sich. ([GitHub](https://github.com/airsonic-advanced/airsonic-advanced/issues/873?utm_source=chatgpt.com "DSub sync/cache with Airsonic 11 dumps all files into main ..."))
|
||||
|
||||
|
||||
**Kurz-Setup-Hinweise:**
|
||||
|
||||
- Installiere [[Navidrome]] (Deb/Flatpak/Docker) und stelle `MUSIC_FOLDER` auf deinen bestehenden Musikordner. Aktiviere ggf. `AutoImportPlaylists`. ([[Navidrome]](https://www.Navidrome.org/docs/usage/configuration-options/?utm_source=chatgpt.com "[[Navidrome]] Configuration Options"))
|
||||
|
||||
- Installiere Strawberry als Desktop-Player und bearbeite Tags/Playlists dort; [[Navidrome]] neu scannen lassen oder Auto-Rescan aktivieren. ([strawberrymusicplayer.org](https://www.strawberrymusicplayer.org/?utm_source=chatgpt.com "Strawberry Music Player"))
|
||||
|
||||
- Auf Android: DSub/Ultrasonic konfigurieren (Server-URL mit deiner lokalen IP), in der App die Download/Transcode-Qualität setzen. ([subsonic.org](https://www.subsonic.org/pages/apps.jsp?utm_source=chatgpt.com "Subsonic Apps"))
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 1. **Playcounts / Metadaten in Strawberry vs. Navidrome**
|
||||
|
||||
- **Wenn du Strawberry „lokal“ (eigene Library, also direkt auf den Musikdateien im Dateisystem) benutzt:**
|
||||
|
||||
- Playcounts und Ratings werden **nur in Strawberries interner Datenbank** gepflegt, nicht in Navidrome.
|
||||
|
||||
- Metadatenänderungen (Tags, Cover etc.), die du in den Dateien speicherst, **sieht Navidrome** beim nächsten Scan (manuell oder automatisch). → Cover/Tags sind also synchron, **aber Playcounts und Ratings nicht**.
|
||||
|
||||
- **Wenn du Strawberry „über Streaming“ mit Navidrome verbindest:**
|
||||
|
||||
- Playcounts und Ratings werden im **Navidrome-Server** gespeichert, d.h. Handy + PC greifen auf denselben Zähler/Rating zurück.
|
||||
|
||||
- Änderungen in der Datei selbst sind dann nachrangig (es sei denn, du editierst die Tags explizit im Dateisystem).
|
||||
|
||||
|
||||
👉 Empfehlung:
|
||||
|
||||
- Für **Playcounts und Bewertungen**, immer über das Navidrome-Streaming-Backend hören.
|
||||
|
||||
- Für **Tag-Bearbeitung** (Album Artist, Genre, Cover etc.) kannst du ruhig Strawberry lokal verwenden → nach dem Speichern erkennt Navidrome die geänderten Tags.
|
||||
|
||||
|
||||
---
|
||||
|
||||
### 2. **Navidrome auf Synology NAS installieren – sinnvoll?**
|
||||
|
||||
- **Ja, absolut sinnvoll.** Vorteile:
|
||||
|
||||
- Deine Musik liegt vermutlich sowieso schon auf der NAS.
|
||||
|
||||
- Navidrome kann 24/7 laufen, unabhängig vom PC.
|
||||
|
||||
- Dein Handy kann direkt auf die NAS zugreifen (auch unterwegs, wenn du Portfreigabe oder VPN einrichtest).
|
||||
|
||||
- Installationsmöglichkeiten:
|
||||
|
||||
- **Docker-Container** (empfohlen, wenn du Docker auf der Synology nutzt). Das offizielle Image ist `deluan/navidrome`.
|
||||
|
||||
- Oder als native Binary in einer Synology-Chroot/Entwicklungsumgebung (Docker ist aber deutlich einfacher).
|
||||
|
||||
|
||||
👉 Empfehlung: Wenn die NAS immer läuft → installiere Navidrome dort. Dann kannst du Strawberry am PC so konfigurieren, dass er sich nur noch als Client auf den NAS-Server verbindet.
|
||||
|
||||
---
|
||||
|
||||
### 3. **Navidrome beim Systemstart automatisch starten lassen**
|
||||
|
||||
Hängt davon ab, wie du es installiert hast:
|
||||
|
||||
- **Systemd-Service (klassisch, wenn du es auf deinem Linux-PC laufen lässt):**
|
||||
|
||||
1. Service-Datei erstellen:
|
||||
|
||||
```ini
|
||||
# /etc/systemd/system/navidrome.service
|
||||
[Unit]
|
||||
Description=Navidrome Music Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=deinuser
|
||||
Group=deinuser
|
||||
ExecStart=/usr/local/bin/navidrome --configfile /etc/navidrome.toml
|
||||
Restart=on-failure
|
||||
WorkingDirectory=/home/deinuser
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
2. Aktivieren & starten:
|
||||
|
||||
```bash
|
||||
sudo systemctl enable navidrome
|
||||
sudo systemctl start navidrome
|
||||
```
|
||||
|
||||
- **Docker + Systemd:**
|
||||
Wenn du Navidrome via Docker laufen lässt, kannst du entweder `docker run --restart=always ...` nutzen oder einen systemd-Service schreiben, der den Container startet.
|
||||
|
||||
- **Synology NAS (Docker):**
|
||||
Die Synology Docker-Oberfläche bietet eine Einstellung **„Automatisch starten“** beim Container an. Einfach anhaken, dann startet Navidrome mit der NAS.
|
||||
|
||||
|
||||
---
|
||||
|
||||
✅ **Kurz zusammengefasst:**
|
||||
|
||||
- **Playcounts/Ratings:** Nur über Navidrome-Streaming → sonst bleiben sie lokal in Strawberry.
|
||||
|
||||
- **Metadaten (Tags, Cover):** Bearbeitung in Strawberry → Navidrome liest sie beim nächsten Scan ein.
|
||||
|
||||
- **NAS:** Ideal für Dauerbetrieb, am besten per Docker.
|
||||
|
||||
- **Autostart:** systemd-Service (Linux) oder Autostart in Synology Docker aktivieren.
|
||||
|
||||
|
||||
---
|
||||
|
||||
👉 Soll ich dir eine konkrete Schritt-für-Schritt-Anleitung für **Navidrome auf Synology NAS (per Docker)** schreiben, inkl. `docker run`-Beispiel und Volume-Mounts (z. B. für `music/` und `data/`)? Dann kannst du deine PC-Instanz ablösen und alles zentralisieren.
|
||||
@@ -0,0 +1,97 @@
|
||||
<https://www.navidrome.org/>
|
||||
|
||||
Hier eine ausführliche Vorstellung von **Navidrome**:
|
||||
|
||||
---
|
||||
|
||||
## 🔎 Was ist Navidrome?
|
||||
|
||||
Navidrome ist ein **selbstgehosteter Musikserver** für \[\[Linux\]\] (und andere Plattformen). Er funktioniert ähnlich wie Spotify oder Apple Music – nur mit deiner eigenen Musikbibliothek. Du lädst deine Audiodateien (MP3, FLAC, OGG, AAC etc.) auf deinen Server, und Navidrome macht sie über ein Web-Interface oder kompatible Apps (\[\[Subsonic-API\]\]) überall verfügbar.
|
||||
|
||||
Kurz:
|
||||
👉 Deine Musik, dein Server, jederzeit und überall streambar.
|
||||
|
||||
---
|
||||
|
||||
## 🎶 Was kann Navidrome?
|
||||
|
||||
- **Streaming im Browser** mit einem modernen, responsiven Webplayer.
|
||||
- **Unterstützt viele Clients** über die Subsonic-API (z. B. \[\[DSub\]\], \[\[Ultrasonic\]\], \[\[Substreamer\]\], Symfonium, etc.).
|
||||
- **Automatische Bibliotheksindizierung**: Scannt Ordner, liest Metadaten und baut deine Mediathek.
|
||||
- **Benutzerverwaltung**: Mehrere Accounts mit eigenen Playlists, Favoriten und Rechten.
|
||||
- **Playlists & Favoriten** (inkl. Smart-Playlists).
|
||||
- **Transcoding on the fly**: Wandelt Dateien in kleinere Formate um, falls deine Verbindung langsam ist.
|
||||
- **Leichtgewichtig & ressourcenschonend** (geschrieben in Go).
|
||||
- **Cross-Plattform**: \[\[Linux\]\], Windows, macOS, ARM (z. B. Raspberry Pi).
|
||||
- **Docker-Images verfügbar** für einfache Installation.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Vorteile gegenüber anderen Lösungen
|
||||
|
||||
- **Leichtgewichtiger als Plex oder Jellyfin**, weil es sich auf Musik konzentriert.
|
||||
- **Moderner und aktiver entwickelt als Airsonic, Subsonic & Co.**
|
||||
- **Einfach zu installieren und zu warten** (ein Binary oder Docker-Container reicht).
|
||||
- **Sehr niedrige Hardware-Anforderungen** – läuft problemlos auf kleinen VPS oder einem Raspberry Pi.
|
||||
- **Sehr gute Client-Kompatibilität** durch \[\[Subsonic-API\]\].
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Installation unter Linux
|
||||
|
||||
### Variante 1: Per Binary (klassisch)
|
||||
|
||||
1. Lade die aktuelle Version herunter:
|
||||
|
||||
```bash
|
||||
wget https://github.com/navidrome/navidrome/releases/latest/download/navidrome_linux_amd64.tar.gz
|
||||
tar xzf navidrome_linux_amd64.tar.gz
|
||||
sudo mv navidrome /usr/local/bin/
|
||||
```
|
||||
2. Erstelle einen Benutzer für Navidrome:
|
||||
|
||||
```bash
|
||||
sudo useradd -r -s /bin/false navidrome
|
||||
```
|
||||
3. Erstelle ein Konfigurationsverzeichnis:
|
||||
|
||||
```bash
|
||||
sudo mkdir /var/lib/navidrome
|
||||
sudo chown navidrome:navidrome /var/lib/navidrome
|
||||
```
|
||||
4. Systemd-Service einrichten (optional).
|
||||
|
||||
---
|
||||
|
||||
### Variante 2: \[\[Docker\]\] (empfohlen)
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name=navidrome \
|
||||
-p 4533:4533 \
|
||||
-v /pfad/zu/deiner/musik:/music \
|
||||
-v /pfad/zu/navidrome/data:/data \
|
||||
deluan/navidrome:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Ersteinrichtung
|
||||
|
||||
- Navidrome läuft nun auf: <http://localhost:4533>
|
||||
- Beim ersten Start wirst du aufgefordert, ein **Admin-Konto** anzulegen.
|
||||
- Danach: Musikordner wird automatisch eingelesen (Metadaten, Cover, etc.).
|
||||
|
||||
---
|
||||
|
||||
## 📌 Dinge, die man beachten sollte
|
||||
|
||||
- **Firewall/Portfreigabe**: Wenn du von außen zugreifen willst, Port 4533 öffnen oder einen Reverse Proxy (nginx/traefik mit HTTPS) davor schalten.
|
||||
- **Sicherung**: Datenbank & Konfigurationsordner `/data` regelmäßig sichern.
|
||||
- **Rechte**: Musikordner muss für den Navidrome-Benutzer lesbar sein.
|
||||
- **Transcoding**: Falls du FLAC → MP3 brauchst, sollte `ffmpeg` installiert sein.
|
||||
- **Clients**: Nutze eine kompatible App für Smartphone-Streaming (z. B. Symfonium [Android], iSub [iOS]).
|
||||
|
||||
---
|
||||
|
||||
\[\[Navidrome mit Strawberry 1\]\]
|
||||
@@ -0,0 +1,99 @@
|
||||
## Debian-basierte Systeme (Ubuntu, Debian, Linux Mint, etc.)
|
||||
|
||||
### APT (Advanced Package Tool)
|
||||
|
||||
```bash
|
||||
# Paketliste aktualisieren
|
||||
sudo apt update
|
||||
|
||||
# Einzelnes Paket installieren
|
||||
sudo apt install paketname
|
||||
|
||||
# Mehrere Pakete installieren
|
||||
sudo apt install paket1 paket2 paket3
|
||||
|
||||
# System-Upgrade durchführen
|
||||
sudo apt upgrade
|
||||
|
||||
# Paket entfernen
|
||||
sudo apt remove paketname
|
||||
|
||||
# Paket komplett entfernen (inkl. Konfigurationsdateien)
|
||||
sudo apt purge paketname
|
||||
|
||||
# Nach Paketen suchen
|
||||
apt search suchbegriff
|
||||
|
||||
# Paketinformationen anzeigen
|
||||
apt show paketname
|
||||
```
|
||||
|
||||
### Alternative: APT-GET (ältere Syntax)
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install paketname
|
||||
sudo apt-get remove paketname
|
||||
```
|
||||
|
||||
## Arch-basierte Systeme (Arch Linux, Manjaro, EndeavourOS, etc.)
|
||||
|
||||
#Pacman (Package Manager)
|
||||
|
||||
```bash
|
||||
# Paketdatenbank synchronisieren
|
||||
sudo pacman -Sy
|
||||
|
||||
# System komplett aktualisieren
|
||||
sudo pacman -Syu
|
||||
|
||||
# Einzelnes Paket installieren
|
||||
sudo pacman -S paketname
|
||||
|
||||
# Mehrere Pakete installieren
|
||||
sudo pacman -S paket1 paket2 paket3
|
||||
|
||||
# Paket entfernen
|
||||
sudo pacman -R paketname
|
||||
|
||||
# Paket mit Abhängigkeiten entfernen
|
||||
sudo pacman -Rs paketname
|
||||
|
||||
# Nach Paketen suchen
|
||||
pacman -Ss suchbegriff
|
||||
|
||||
# Installierte Pakete auflisten
|
||||
pacman -Q
|
||||
|
||||
# Paketinformationen anzeigen
|
||||
pacman -Si paketname
|
||||
```
|
||||
|
||||
### AUR (Arch User Repository)
|
||||
Für AUR-Pakete wird ein AUR-Helper wie `yay` oder `paru` benötigt:
|
||||
|
||||
```bash
|
||||
# Mit yay installieren
|
||||
yay -S paketname
|
||||
|
||||
# Mit paru installieren
|
||||
paru -S paketname
|
||||
```
|
||||
|
||||
## Wichtige Parameter-Erklärungen
|
||||
|
||||
| Debian (apt) | Arch (pacman) | Bedeutung |
|
||||
|--------------|---------------|-----------|
|
||||
| `update` | `-Sy` | Paketliste aktualisieren |
|
||||
| `upgrade` | `-Su` | Installierte Pakete aktualisieren |
|
||||
| `install` | `-S` | Paket installieren |
|
||||
| `remove` | `-R` | Paket entfernen |
|
||||
| `search` | `-Ss` | Nach Paketen suchen |
|
||||
| `show` | `-Si` | Paketinformationen anzeigen |
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Immer vor Installation**: System aktualisieren
|
||||
- **Debian**: `sudo apt update && sudo apt upgrade`
|
||||
- **Arch**: `sudo pacman -Syu`
|
||||
|
||||
> **Tipp**: Auf Arch-Systemen sollte man niemals `pacman -Sy paketname` ohne vorheriges vollständiges System-Update verwenden, da dies zu Abhängigkeitsproblemen führen kann.
|
||||
@@ -0,0 +1,101 @@
|
||||
|
||||
|
||||
Um dich per **SSH** zwischen zwei Linux-Rechnern im Heimnetzwerk zu verbinden, gehst du so vor:
|
||||
|
||||
---
|
||||
|
||||
### 1. SSH-Server installieren und aktivieren
|
||||
|
||||
Auf dem Rechner, **zu dem du dich verbinden möchtest** (Zielrechner):
|
||||
|
||||
```bash
|
||||
sudo apt update && sudo apt install openssh-server -y # Ubuntu/Debian
|
||||
sudo systemctl enable ssh
|
||||
sudo systemctl start ssh
|
||||
```
|
||||
|
||||
Auf Fedora/RHEL/Arch:
|
||||
|
||||
```bash
|
||||
sudo dnf install openssh-server -y # Fedora
|
||||
sudo pacman -S openssh # Arch
|
||||
sudo systemctl enable sshd
|
||||
sudo systemctl start sshd
|
||||
```
|
||||
|
||||
Status prüfen:
|
||||
|
||||
```bash
|
||||
systemctl status ssh
|
||||
```
|
||||
|
||||
oder
|
||||
|
||||
```bash
|
||||
systemctl status sshd
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. IP-Adresse des Zielrechners herausfinden
|
||||
|
||||
Auf dem Zielrechner:
|
||||
|
||||
```bash
|
||||
ip a
|
||||
```
|
||||
|
||||
oder
|
||||
|
||||
```bash
|
||||
hostname -I
|
||||
```
|
||||
|
||||
Beispielausgabe: `192.168.178.42`
|
||||
|
||||
---
|
||||
|
||||
### 3. Verbindung vom Quellrechner herstellen
|
||||
|
||||
Auf dem Rechner, von dem du zugreifen willst:
|
||||
|
||||
```bash
|
||||
ssh benutzername@192.168.178.42
|
||||
```
|
||||
|
||||
Dabei:
|
||||
|
||||
- `benutzername` = Benutzerkonto auf dem Zielrechner
|
||||
- `192.168.178.42` = IP-Adresse des Zielrechners im Heimnetz
|
||||
|
||||
Beim ersten Mal wirst du gefragt, ob du den Host-Fingerprint akzeptieren willst → `yes`. Danach gibst du dein Passwort ein.
|
||||
|
||||
---
|
||||
|
||||
### 4. (Optional) Passwortlose Anmeldung mit SSH-Key
|
||||
|
||||
Falls du dich ohne Passwort anmelden willst:
|
||||
|
||||
Auf dem Quellrechner:
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519
|
||||
```
|
||||
|
||||
(oder `rsa` falls gewünscht, einfach Enter drücken, um Standardpfad `~/.ssh/id_ed25519` zu nutzen)
|
||||
|
||||
Dann den öffentlichen Schlüssel auf den Zielrechner kopieren:
|
||||
|
||||
```bash
|
||||
ssh-copy-id benutzername@192.168.178.42
|
||||
```
|
||||
|
||||
Danach kannst du dich einloggen ohne Passwort:
|
||||
|
||||
```bash
|
||||
ssh benutzername@192.168.178.42
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
👉 Soll ich dir ein **kurzes Beispiel-Setup mit zwei Testbenutzern** schreiben, das du direkt im Heimnetz nachmachen kannst?
|
||||
@@ -0,0 +1,162 @@
|
||||
### 🔧 1. SSH-Schlüssel erzeugen
|
||||
|
||||
Öffne ein Terminal und gib ein:
|
||||
|
||||
```bash
|
||||
ssh-keygen -t ed25519 -C "dein.name@beispiel.de"
|
||||
```
|
||||
|
||||
- `-t ed25519`: moderner, sicherer Schlüsseltyp (alternativ: `rsa`).
|
||||
- `-C`: Kommentar zur Identifikation (z. B. deine E-Mail).
|
||||
|
||||
**Wenn gefragt:**
|
||||
|
||||
- Speicherort bestätigen mit **Enter** (Standard: `~/.ssh/id_ed25519`).
|
||||
- Optional ein **Passwort** setzen (empfohlen für zusätzliche Sicherheit).
|
||||
|
||||
---
|
||||
|
||||
### 📤 2. Öffentlichen Schlüssel auf den Server kopieren
|
||||
|
||||
Wenn du z. B. Zugriff auf `user@server.de` hast:
|
||||
|
||||
```bash
|
||||
ssh-copy-id user@server.de
|
||||
```
|
||||
|
||||
Falls `ssh-copy-id` nicht installiert ist, kannst du den Schlüssel auch manuell übertragen:
|
||||
|
||||
```bash
|
||||
cat ~/.ssh/id_ed25519.pub
|
||||
```
|
||||
|
||||
Dann den Inhalt in die Datei `~/.ssh/authorized_keys` auf dem Server einfügen.
|
||||
|
||||
---
|
||||
|
||||
### 🔐 3. Mit dem Server verbinden
|
||||
|
||||
Danach kannst du dich einfach per SSH einloggen:
|
||||
|
||||
```bash
|
||||
ssh user@server.de
|
||||
```
|
||||
|
||||
Du wirst **nicht mehr nach dem Passwort des Servers** gefragt – nur ggf. nach der Passphrase deines privaten Schlüssels.
|
||||
|
||||
---
|
||||
|
||||
### 🧩 (Optional) 4. SSH-Agent verwenden
|
||||
|
||||
Damit du die Passphrase nicht ständig eingeben musst:
|
||||
|
||||
```bash
|
||||
eval "$(ssh-agent -s)"
|
||||
ssh-add ~/.ssh/id_ed25519
|
||||
```
|
||||
|
||||
---
|
||||
Wenn `git push` weiterhin nach einem Passwort fragt, liegt das fast immer daran, dass dein Repository **über HTTPS statt SSH** verbunden ist.
|
||||
|
||||
Lass uns das prüfen und beheben 👇
|
||||
|
||||
---
|
||||
|
||||
## 🔎 1️⃣ Prüfen, welche Remote-URL verwendet wird
|
||||
|
||||
Im Repository:
|
||||
|
||||
```bash
|
||||
git remote -v
|
||||
```
|
||||
|
||||
Wenn du etwas siehst wie:
|
||||
|
||||
```
|
||||
https://github.com/USERNAME/REPO.git
|
||||
```
|
||||
|
||||
➡ Dann nutzt du **HTTPS** – deshalb wird ein Passwort (bzw. Token) verlangt.
|
||||
|
||||
Wenn dort steht:
|
||||
|
||||
```
|
||||
git@github.com:USERNAME/REPO.git
|
||||
```
|
||||
|
||||
➡ Das ist korrekt (SSH).
|
||||
|
||||
---
|
||||
|
||||
## 🔁 2️⃣ Remote von HTTPS auf SSH umstellen
|
||||
|
||||
Ersetze die URL mit der SSH-Version:
|
||||
|
||||
```bash
|
||||
git remote set-url origin git@github.com:USERNAME/REPO.git
|
||||
```
|
||||
|
||||
Danach nochmal testen:
|
||||
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 3️⃣ SSH-Verbindung separat testen
|
||||
|
||||
```bash
|
||||
ssh -T git@github.com
|
||||
```
|
||||
|
||||
Du solltest eine Meldung bekommen wie:
|
||||
|
||||
```
|
||||
Hi USERNAME! You've successfully authenticated...
|
||||
```
|
||||
|
||||
Wenn nicht, sag mir bitte die Fehlermeldung.
|
||||
|
||||
---
|
||||
|
||||
## 🔐 4️⃣ Falls SSH korrekt ist, aber trotzdem Passwort kommt
|
||||
|
||||
Dann prüfen:
|
||||
|
||||
### Läuft der SSH-Agent?
|
||||
|
||||
```bash
|
||||
ssh-add -l
|
||||
```
|
||||
|
||||
Wenn dort steht:
|
||||
|
||||
```
|
||||
The agent has no identities.
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```bash
|
||||
ssh-add ~/.ssh/id_ed25519
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛠 5️⃣ Debug-Modus (wenn es immer noch nicht klappt)
|
||||
|
||||
```bash
|
||||
ssh -vT git@github.com
|
||||
```
|
||||
|
||||
Das zeigt, welcher Key wirklich benutzt wird.
|
||||
|
||||
---
|
||||
|
||||
### 💡 90% der Fälle:
|
||||
|
||||
Das Repository wurde ursprünglich per HTTPS geklont.
|
||||
|
||||
Wenn du möchtest, kannst du mir die Ausgabe von
|
||||
`git remote -v` posten – dann sage ich dir exakt, was los ist.
|
||||
@@ -0,0 +1,137 @@
|
||||
Strawberry ist ein **Musikplayer und -manager** für [[Linux]] (auch für Windows und macOS verfügbar), der sich auf **lokale Musiksammlungen** konzentriert. Er ist ein Fork von _Clementine_, das wiederum auf _Amarok_ basiert. Strawberry richtet sich vor allem an Nutzer, die eine **große Sammlung an Musikdateien (MP3, FLAC, OGG, etc.) lokal verwalten** möchten – im Gegensatz zu Playern, die stark auf Streaming setzen.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Zweck von Strawberry
|
||||
|
||||
- **Abspielen von Musikdateien** in allen gängigen Formaten.
|
||||
|
||||
- **Bibliotheksverwaltung**: Organisieren großer Sammlungen anhand von Metadaten, Tags und Ordnerstrukturen.
|
||||
|
||||
- **Metadatenverwaltung**: Bearbeiten von Tags, Laden von Cover-Artworks, Abgleich mit Online-Datenbanken (z. B. MusicBrainz).
|
||||
|
||||
- **Wiedergabelisten**: Erstellen und Verwalten komplexer Playlists.
|
||||
|
||||
- **Audiowiedergabe in hoher Qualität** mit Unterstützung von Hi-Res-Formaten.
|
||||
|
||||
- **Externe Dienste**: Scrobbling zu Last.fm, Libre.fm oder ListenBrainz.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Funktionen
|
||||
|
||||
- Unterstützung für FLAC, MP3, OGG, WAV, WMA, AAC u. v. m.
|
||||
|
||||
- Wiedergabe mit **GStreamer** (gute Audioqualität, viele Codecs).
|
||||
|
||||
- **Tag-Editor** für ID3, Vorbis- und FLAC-Tags.
|
||||
|
||||
- Automatisches Laden von **Album-Covern**.
|
||||
|
||||
- **EQ und ReplayGain**-Unterstützung.
|
||||
|
||||
- **Wiedergabelisten** im M3U-, XSPF- und PLS-Format.
|
||||
|
||||
- **Gerätesynchronisation**: Musik auf mobile Player kopieren.
|
||||
|
||||
- **Streaming-Radio** (einfache Integration, aber nicht Hauptfokus).
|
||||
|
||||
|
||||
---
|
||||
|
||||
## ✅ Vorteile
|
||||
|
||||
- **Fokus auf lokale Musik** – ideal für Sammler, die ihre eigene Bibliothek pflegen.
|
||||
|
||||
- **Schnell und ressourcenschonend** im Vergleich zu schwergewichtigeren Lösungen wie Amarok.
|
||||
|
||||
- **Moderne Code-Basis**: aktiver Fork von Clementine mit Bugfixes und Verbesserungen.
|
||||
|
||||
- **Hohe Audioqualität** mit vielen Formaten und Hi-Res-Support.
|
||||
|
||||
- **Cross-Platform**: Linux, Windows, macOS.
|
||||
|
||||
- **Keine Zwangs-Cloud-Anbindung** wie bei Spotify & Co.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## ❌ Nachteile
|
||||
|
||||
- **Kein nativer Streaming-Fokus** (nur begrenzte Unterstützung für Online-Dienste, keine direkte Spotify-/Apple-Music-Integration).
|
||||
|
||||
- **Eher klassische Oberfläche** – wirkt funktional, aber nicht besonders modern/minimalistisch.
|
||||
|
||||
- **Weniger Community als bei großen Projekten** (z. B. Rhythmbox oder VLC).
|
||||
|
||||
- **Kein eigener mobiler Client** – Synchronisation nur über Dateiübertragung.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 💻 Installation
|
||||
|
||||
### Unter Ubuntu/Debian
|
||||
|
||||
```bash
|
||||
sudo apt install strawberry
|
||||
```
|
||||
|
||||
Falls nicht im Standard-Repo (bei älteren Versionen):
|
||||
|
||||
```bash
|
||||
sudo add-apt-repository ppa:jonaski/strawberry
|
||||
sudo apt update
|
||||
sudo apt install strawberry
|
||||
```
|
||||
|
||||
### Unter Fedora
|
||||
|
||||
```bash
|
||||
sudo dnf install strawberry
|
||||
```
|
||||
|
||||
### Unter Arch Linux / Manjaro
|
||||
|
||||
```bash
|
||||
sudo pacman -S strawberry
|
||||
```
|
||||
|
||||
### Alternative: Flatpak (universell)
|
||||
|
||||
```bash
|
||||
flatpak install flathub org.strawberrymusicplayer.strawberry
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Einrichtung
|
||||
|
||||
1. **Musikordner hinzufügen**: Beim ersten Start fragt Strawberry nach Verzeichnissen, in denen Musik liegt.
|
||||
|
||||
2. **Bibliothek scannen**: Die Dateien werden eingelesen und nach Tags sortiert.
|
||||
|
||||
3. **Audioausgabe konfigurieren**: In den Einstellungen (z. B. ALSA, PulseAudio, PipeWire auswählen).
|
||||
|
||||
4. **Metadaten-Services aktivieren**: Verknüpfung mit MusicBrainz, Last.fm oder Libre.fm, wenn gewünscht.
|
||||
|
||||
5. **Wiedergabelisten und Cover laden**: Automatisches Suchen und Speichern aktivieren.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 📌 Was man beachten sollte
|
||||
|
||||
- Strawberry ist für **Sammler und Audiophile** gedacht – wenn man hauptsächlich Spotify oder YouTube nutzt, ist es weniger passend.
|
||||
|
||||
- Gute Organisation der Musikordner und Tags erleichtert die Verwaltung erheblich.
|
||||
|
||||
- Bei **Hi-Res-Audio**: Prüfen, ob das Audiosystem (ALSA/PipeWire) korrekt konfiguriert ist.
|
||||
|
||||
- Für große Bibliotheken (>100.000 Tracks) sollte man auf genügend RAM und eine SSD achten, sonst wird die Suche langsam.
|
||||
|
||||
|
||||
---
|
||||
|
||||
👉 Soll ich dir eine Schritt-für-Schritt-Anleitung schreiben, wie du Strawberry nach der Installation optimal für eine große Musiksammlung einrichtest (inkl. Cover, Tags, Audio-Einstellungen)?
|
||||
@@ -0,0 +1,119 @@
|
||||
Perfekt – dann ist eine Subsonic-kompatible Library genau das, was du suchst 👍
|
||||
|
||||
Für [[Python]] gibt es z. B. [`py-sonic`](https://github.com/crustymonkey/py-sonic).
|
||||
Die ist zwar nicht mehr super aktiv gepflegt, funktioniert aber mit [[Navidrome]] problemlos, weil Navidrome die [[Subsonic-API]] spricht.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install py-sonic
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Grund-Setup
|
||||
|
||||
```python
|
||||
from pysonic.connection import Connection
|
||||
|
||||
# Verbindung aufbauen
|
||||
conn = Connection(
|
||||
host="http://localhost:4533",
|
||||
username="meinuser",
|
||||
password="meinpass",
|
||||
api_version="1.16.1",
|
||||
client_name="pyclient"
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Anwendungsfälle
|
||||
|
||||
### 1. Playlist erstellen oder öffnen
|
||||
|
||||
```python
|
||||
# Neue Playlist
|
||||
playlist = conn.create_playlist("Importierte M3U Playlist")
|
||||
|
||||
# Alle Playlists abfragen
|
||||
all_playlists = conn.get_playlists()
|
||||
```
|
||||
|
||||
### 2. Tracks suchen (z. B. per Filename, Titel, Artist)
|
||||
|
||||
```python
|
||||
search = conn.search2(query="Songtitel", songCount=5)
|
||||
for song in search['song']:
|
||||
print(song['id'], song['title'], song['artist'])
|
||||
```
|
||||
|
||||
### 3. Track zur Playlist hinzufügen
|
||||
|
||||
```python
|
||||
conn.update_playlist(
|
||||
playlist_id=playlist['id'],
|
||||
song_id=["12345", "67890"] # mehrere IDs möglich
|
||||
)
|
||||
```
|
||||
|
||||
### 4. Stern vergeben
|
||||
|
||||
```python
|
||||
conn.star("12345") # Song-ID
|
||||
```
|
||||
|
||||
### 5. Bookmark setzen
|
||||
|
||||
```python
|
||||
conn.create_bookmark("12345", position=60000, comment="Kapitel 1")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Workflow: M3U importieren
|
||||
|
||||
Du kannst einfach durch deine `.m3u`-Datei iterieren, für jede Zeile versuchen, den Track im Navidrome zu finden, und dann Aktionen ausführen:
|
||||
|
||||
```python
|
||||
def import_m3u_to_navidrome(m3u_path, playlist_name):
|
||||
# Playlist anlegen
|
||||
playlist = conn.create_playlist(playlist_name)
|
||||
playlist_id = playlist['id']
|
||||
|
||||
with open(m3u_path, encoding="utf-8") as f:
|
||||
for line in f:
|
||||
if line.startswith("#") or not line.strip():
|
||||
continue
|
||||
filename = line.strip().split("/")[-1] # nur Dateiname
|
||||
|
||||
# Suche im Server
|
||||
search = conn.search2(query=filename, songCount=1)
|
||||
if 'song' in search and search['song']:
|
||||
song = search['song'][0]
|
||||
song_id = song['id']
|
||||
|
||||
# Playlist hinzufügen
|
||||
conn.update_playlist(playlist_id=playlist_id, song_id=[song_id])
|
||||
|
||||
# Stern setzen
|
||||
conn.star(song_id)
|
||||
|
||||
# Bookmark bei 0 (Startpunkt)
|
||||
conn.create_bookmark(song_id, position=0, comment="Importiert aus M3U")
|
||||
|
||||
print(f"→ {filename} gefunden und verarbeitet.")
|
||||
else:
|
||||
print(f"⚠ {filename} nicht gefunden.")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
👉 Damit hättest du ziemlich genau deinen beschriebenen Workflow:
|
||||
M3U → Tracks auflösen → Playlist + Sterne + Bookmarks automatisch setzen.
|
||||
|
||||
---
|
||||
|
||||
Soll ich dir ein **vollständiges Script** bauen, das direkt eine `.m3u` einliest, die passende Playlist erstellt und alle drei Aktionen (Playlist-Eintrag, Stern, Bookmark) in einem Durchlauf macht?
|
||||
@@ -0,0 +1,472 @@
|
||||
Alles klar – ich gebe dir eine ausführliche Übersicht über **Dateisynchronisation und Backups unter Linux**, gegliedert nach typischen Anwendungsfällen (1-way Backup, 2-way Sync, Spezialfälle). Dazu zeige ich dir jeweils **interessante Funktionen**, **geeignete Tools** und **Code-Beispiele**, die du direkt ausprobieren kannst.
|
||||
|
||||
---
|
||||
|
||||
# 🔧 Dateisynchronisation und Backup unter Linux
|
||||
|
||||
## 1. Grundsätzliche Anwendungsfälle
|
||||
|
||||
1. **Backup (1-way Synchronisation)**
|
||||
|
||||
- Ziel: Sicherung von Daten von Quelle → Ziel.
|
||||
|
||||
- Änderungen im Quellordner werden ins Ziel kopiert.
|
||||
|
||||
- Änderungen im Ziel haben keine Wirkung zurück.
|
||||
|
||||
- Typisch für:
|
||||
|
||||
- Regelmäßige Datensicherungen (lokal oder auf Server/NAS)
|
||||
|
||||
- Snapshots und inkrementelle Backups
|
||||
|
||||
2. **Zwei-Wege-Synchronisation (2-way)**
|
||||
|
||||
- Ziel: Quell- und Zielordner sind identisch.
|
||||
|
||||
- Änderungen in beiden Richtungen werden abgeglichen.
|
||||
|
||||
- Typisch für:
|
||||
|
||||
- Zusammenarbeit zwischen Geräten
|
||||
|
||||
- Synchronisation von Arbeitsordnern mit Netzwerkfreigaben oder Cloud
|
||||
|
||||
3. **Weitere Anwendungsbeispiele**
|
||||
|
||||
- **Offsite-Backup** (z. B. automatisches Backup auf einen entfernten Server via SSH)
|
||||
|
||||
- **Versionierte Backups** (Aufbewahrung älterer Stände)
|
||||
|
||||
- **On-the-fly Synchronisation** (z. B. Watcher, der beim Speichern sofort sync’ed)
|
||||
|
||||
- **Mobile Synchronisation** (z. B. Laptop ↔ NAS, USB-Stick ↔ Rechner)
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 2. Tools für 1-way Backups
|
||||
|
||||
### a) **rsync** (Klassiker)
|
||||
|
||||
Das meistgenutzte Werkzeug, effizient und flexibel.
|
||||
|
||||
**Einfaches Backup:**
|
||||
|
||||
```bash
|
||||
rsync -avh /home/user/Dokumente/ /media/backup/Dokumente/
|
||||
```
|
||||
|
||||
- `-a` = Archivmodus (erhält Rechte, Zeiten, Links)
|
||||
|
||||
- `-v` = verbose
|
||||
|
||||
- `-h` = menschenlesbare Größen
|
||||
|
||||
|
||||
**Mit Löschen (Spiegelung):**
|
||||
|
||||
```bash
|
||||
rsync -avh --delete /home/user/Dokumente/ /media/backup/Dokumente/
|
||||
```
|
||||
|
||||
→ Dateien, die in Quelle gelöscht wurden, werden auch im Ziel gelöscht.
|
||||
|
||||
**Über SSH (z. B. auf NAS oder Server):**
|
||||
|
||||
```bash
|
||||
rsync -avz /home/user/Dokumente/ user@server:/backup/Dokumente/
|
||||
```
|
||||
|
||||
- `-z` = Kompression
|
||||
|
||||
|
||||
**Interessante Funktionen:**
|
||||
|
||||
- `--exclude "*.tmp"` → bestimmte Dateien ignorieren
|
||||
|
||||
- `--progress` → Fortschrittsanzeige
|
||||
|
||||
- `--link-dest` → inkrementelle Backups mit Hardlinks (ähnlich Time Machine)
|
||||
|
||||
|
||||
---
|
||||
|
||||
### b) **borgbackup** (für versionierte, komprimierte, verschlüsselte Backups)
|
||||
|
||||
Ideal für langfristige Backups mit Versionierung.
|
||||
|
||||
```bash
|
||||
borg init --encryption=repokey /media/backup/repo
|
||||
borg create --progress /media/backup/repo::2025-09-26 /home/user/Dokumente
|
||||
```
|
||||
|
||||
Später kannst du ältere Versionen wiederherstellen.
|
||||
|
||||
---
|
||||
|
||||
## 3. Tools für 2-way Synchronisation
|
||||
|
||||
### a) **unison**
|
||||
|
||||
Ein Klassiker für bidirektionale Synchronisation.
|
||||
|
||||
**Einfacher Start:**
|
||||
|
||||
```bash
|
||||
unison /home/user/Dokumente ssh://user@server//home/user/Dokumente
|
||||
```
|
||||
|
||||
- Erkennt Änderungen auf beiden Seiten
|
||||
|
||||
- Fragt bei Konflikten nach
|
||||
|
||||
- Arbeitet ähnlich wie `rsync`, aber **beidseitig**
|
||||
|
||||
|
||||
**Dauerhafte Konfiguration:**
|
||||
In `~/.unison/default.prf`:
|
||||
|
||||
```
|
||||
root = /home/user/Dokumente
|
||||
root = ssh://user@server//home/user/Dokumente
|
||||
auto = true
|
||||
batch = true
|
||||
```
|
||||
|
||||
Dann reicht:
|
||||
|
||||
```bash
|
||||
unison
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### b) **Syncthing** (komfortabel mit Weboberfläche)
|
||||
|
||||
- Peer-to-Peer Synchronisation (Ende-zu-Ende verschlüsselt)
|
||||
|
||||
- Cross-Platform (Linux, Windows, Android, macOS)
|
||||
|
||||
- Ideal für nahtlose Syncs ohne manuellen Eingriff
|
||||
|
||||
|
||||
Installation:
|
||||
|
||||
```bash
|
||||
sudo apt install syncthing
|
||||
syncthing
|
||||
```
|
||||
|
||||
→ Startet Weboberfläche auf [http://127.0.0.1:8384](http://127.0.0.1:8384)
|
||||
|
||||
---
|
||||
|
||||
## 4. Automatisierung
|
||||
|
||||
### a) Cron-Jobs für regelmäßige Backups
|
||||
|
||||
Beispiel: Täglich um 3 Uhr ein rsync-Backup:
|
||||
|
||||
```bash
|
||||
0 3 * * * rsync -avh --delete /home/user/Dokumente/ /media/backup/Dokumente/
|
||||
```
|
||||
|
||||
(`crontab -e`)
|
||||
|
||||
### b) systemd Timer (moderner als Cron)
|
||||
|
||||
Service-Unit (`/etc/systemd/system/backup.service`):
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Backup Dokumente
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/rsync -avh --delete /home/user/Dokumente/ /media/backup/Dokumente/
|
||||
```
|
||||
|
||||
Timer (`/etc/systemd/system/backup.timer`):
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Backup Timer
|
||||
|
||||
[Timer]
|
||||
OnCalendar=daily
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
```
|
||||
|
||||
Aktivieren:
|
||||
|
||||
```bash
|
||||
sudo systemctl enable --now backup.timer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Zusammenfassung der interessantesten Funktionen
|
||||
|
||||
- **rsync** → universell, effizient, für Backups und Spiegelungen
|
||||
|
||||
- **borgbackup** → versioniert, verschlüsselt, platzsparend
|
||||
|
||||
- **unison** → 2-way Sync mit Konfliktlösung
|
||||
|
||||
- **syncthing** → benutzerfreundlich, kontinuierliche Synchronisation
|
||||
|
||||
|
||||
---
|
||||
|
||||
👉 Tipp:
|
||||
Wenn du **nur Backups** brauchst → `rsync` oder `borg`.
|
||||
Wenn du **aktive Ordner synchron halten willst** → `unison` oder `syncthing`.
|
||||
|
||||
---
|
||||
|
||||
Soll ich dir zum Einstieg ein **komplettes Setup-Skript für ein automatisches tägliches Backup mit rsync** schreiben, das du direkt verwenden kannst?
|
||||
Sehr gute Fragen 👍 — ich gehe das mit dir systematisch durch.
|
||||
|
||||
---
|
||||
|
||||
# 🔄 Unison: Verhalten, Hintergrundbetrieb & Performance
|
||||
|
||||
## 1. Läuft Unison permanent im Hintergrund?
|
||||
|
||||
Unison an sich ist **kein permanenter Daemon** wie etwa Syncthing.
|
||||
Es funktioniert normalerweise so:
|
||||
|
||||
- Du startest Unison → es vergleicht Quelle und Ziel → synchronisiert → beendet sich.
|
||||
|
||||
- Du kannst es per Cron, systemd-Timer oder manuell regelmäßig ausführen.
|
||||
|
||||
- Es gibt aber einen **"Unison-GUI/Repeat-Modus"**, bei dem es in einer Schleife läuft und z. B. alle 10 Sekunden die Verzeichnisse prüft.
|
||||
|
||||
|
||||
Beispiel für wiederholte Synchronisation:
|
||||
|
||||
```bash
|
||||
unison default -repeat watch
|
||||
```
|
||||
|
||||
- `-repeat watch` = Unison nutzt OS-Funktionalitäten (inotify auf Linux), um Änderungen sofort zu erkennen.
|
||||
|
||||
- `-repeat 10` = alternativ: Polling alle 10 Sekunden.
|
||||
|
||||
|
||||
Damit verhält sich Unison _fast_ wie Syncthing, aber ist weniger komfortabel, weil es keinen richtigen Daemon hat.
|
||||
|
||||
---
|
||||
|
||||
## 2. Start bei Systemstart
|
||||
|
||||
Damit Unison automatisch startet, kannst du es mit **systemd** einrichten.
|
||||
|
||||
### Beispiel: systemd Service-Datei
|
||||
|
||||
`~/.config/systemd/user/unison.service`
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Unison sync service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/unison default -repeat watch
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
```
|
||||
|
||||
Dann aktivieren:
|
||||
|
||||
```bash
|
||||
systemctl --user enable --now unison.service
|
||||
```
|
||||
|
||||
→ Jetzt läuft Unison beim Login des Users automatisch und überwacht die definierten Profile.
|
||||
|
||||
---
|
||||
|
||||
## 3. Performance Impact
|
||||
|
||||
Die Performance hängt von der Betriebsart ab:
|
||||
|
||||
- **Einmalige Ausführung (Standard)**
|
||||
|
||||
- Minimaler Impact, nur während der Synchronisation.
|
||||
|
||||
- Nutzt Hashing/Datei-Checksummen, um Änderungen effizient zu erkennen.
|
||||
|
||||
- Bei großen Verzeichnissen ist der **erste Lauf** teuer (voller Indexaufbau), danach werden nur Änderungen geprüft.
|
||||
|
||||
- **Dauerbetrieb mit `-repeat watch`**
|
||||
|
||||
- Nutzt `inotify` → kaum CPU-Last, da nur Änderungen getriggert werden.
|
||||
|
||||
- Speicherbedarf: wenige Dutzend MB RAM.
|
||||
|
||||
- CPU-Last: fast 0, außer wenn aktiv synchronisiert wird.
|
||||
|
||||
- **Dauerbetrieb mit `-repeat 10` (Polling)**
|
||||
|
||||
- Alle 10 Sekunden kompletter Scan → deutlich mehr I/O bei vielen Dateien.
|
||||
|
||||
- Sollte nur verwendet werden, wenn `inotify` nicht funktioniert (z. B. bei Netzwerk-Dateisystemen).
|
||||
|
||||
|
||||
**Kurz:**
|
||||
|
||||
- Lokale Ordner: `-repeat watch` → sehr effizient
|
||||
|
||||
- Netzwerk-Mounts (NFS, SMB): oft kein inotify → Polling nötig, etwas schwerer
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 4. Fazit
|
||||
|
||||
- Unison ist **keine Always-on-Synchronisation wie Syncthing**, aber mit `-repeat watch` + systemd lässt es sich quasi gleichwertig nutzen.
|
||||
|
||||
- Performance-Impact ist sehr gering, solange du `watch` nutzt.
|
||||
|
||||
- Für **regelmäßige Backups** → Cron oder systemd Timer reicht.
|
||||
|
||||
- Für **nahezu Echtzeit-Sync** → `-repeat watch` + systemd Service ist die beste Lösung.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
## 1. Voraussetzung: Config-Datei
|
||||
|
||||
Ja, korrekt ✅
|
||||
Der Aufruf
|
||||
|
||||
```bash
|
||||
unison default -repeat watch
|
||||
```
|
||||
|
||||
setzt voraus, dass du eine Konfigurationsdatei `~/.unison/default.prf` hast.
|
||||
Dort definierst du z. B.:
|
||||
|
||||
```txt
|
||||
root = /home/user/Dokumente
|
||||
root = ssh://user@server//home/user/Dokumente
|
||||
|
||||
auto = true
|
||||
batch = true
|
||||
```
|
||||
|
||||
- **`auto = true`** → versucht, Konflikte automatisch zu lösen (kein Nachfragen bei eindeutigen Fällen).
|
||||
|
||||
- **`batch = true`** → führt ohne Interaktion aus.
|
||||
|
||||
- Falls Konflikte auftreten, entscheidet er nach den Regeln oder verweigert Sync.
|
||||
|
||||
- Ohne `batch` würdest du wieder Fragen im Terminal sehen.
|
||||
|
||||
|
||||
👉 Empfehlung: Für systemd immer `auto = true` und `batch = true` setzen, sonst blockiert der Prozess.
|
||||
|
||||
---
|
||||
|
||||
## 2. Rückfragen vermeiden (Default-Verhalten)
|
||||
|
||||
Wie du beobachtet hast, fragt Unison bei `unison [quelle] [ziel]` ohne Konfig bei **Konflikten** („Welche Version behalten?“).
|
||||
|
||||
- Mit **Konfig + batch + auto** → keine Rückfragen.
|
||||
|
||||
- Du kannst zusätzlich Regeln setzen, z. B.:
|
||||
|
||||
|
||||
```txt
|
||||
prefer = newer # Immer die neuere Version behalten
|
||||
prefer = /home/user # Lokale Version gewinnt
|
||||
```
|
||||
|
||||
Das ist wichtig für den systemd-Einsatz, weil ein Dienst nicht sinnvoll auf Eingaben warten kann.
|
||||
|
||||
---
|
||||
|
||||
## 3. Logging
|
||||
|
||||
### a) Standardmäßig
|
||||
|
||||
Unison schreibt **keine dauerhaften Logs** von sich aus.
|
||||
Die Ausgaben gehen in `stdout/stderr` → wenn du es manuell startest, siehst du es im Terminal.
|
||||
|
||||
### b) Mit systemd
|
||||
|
||||
systemd fängt alles auf → mit
|
||||
|
||||
```bash
|
||||
journalctl --user -u unison.service
|
||||
```
|
||||
|
||||
siehst du die Logs.
|
||||
Wenn dir das reicht, brauchst du nichts extra.
|
||||
|
||||
### c) Eigene Logdateien
|
||||
|
||||
Du kannst in der `.prf`-Datei angeben:
|
||||
|
||||
```txt
|
||||
log = /var/log/unison/unison.log
|
||||
```
|
||||
|
||||
oder direkt beim Start per `ExecStart`:
|
||||
|
||||
```ini
|
||||
ExecStart=/usr/bin/unison default -repeat watch -logfile /var/log/unison/unison.log
|
||||
```
|
||||
|
||||
### d) Alte Logs automatisch löschen
|
||||
|
||||
Unison selbst rotiert keine Logs, aber systemd oder `logrotate` kann das übernehmen.
|
||||
Beispiel `logrotate`-Konfig (`/etc/logrotate.d/unison`):
|
||||
|
||||
```
|
||||
/var/log/unison/unison.log {
|
||||
daily
|
||||
rotate 30
|
||||
compress
|
||||
missingok
|
||||
notifempty
|
||||
create 640 user user
|
||||
}
|
||||
```
|
||||
|
||||
→ Hält 30 Tage Logs, dann werden sie komprimiert/gelöscht.
|
||||
|
||||
Wenn du lieber pro Sitzung in `/tmp` loggen willst:
|
||||
|
||||
```ini
|
||||
ExecStart=/usr/bin/unison default -repeat watch -logfile /tmp/unison-%u.log
|
||||
```
|
||||
|
||||
und ein Cronjob/systemd-Timer löscht alte Dateien:
|
||||
|
||||
```bash
|
||||
find /tmp -name 'unison-*.log' -mtime +30 -delete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Fazit
|
||||
|
||||
- **Ja**, Config-Datei nötig → dort Batch/Auto einstellen.
|
||||
|
||||
- **Default-Verhalten einstellen** mit `prefer`-Regeln, sonst blockieren Konflikte.
|
||||
|
||||
- **Logs**: systemd-Journal reicht oft, alternativ eigene Logdatei + logrotate.
|
||||
|
||||
|
||||
---
|
||||
|
||||
👉 Soll ich dir eine **komplette Beispielkonfig `default.prf` + passende systemd-Service-Datei** basteln, die direkt „Headless-Sync im Hintergrund“ macht inkl. Log-Rotation?
|
||||
@@ -0,0 +1,230 @@
|
||||
# Timeshift Kommandozeilen-Nutzung
|
||||
|
||||
## Überblick
|
||||
Timeshift ist ein Backup-Tool für Linux-Systeme, das System-Snapshots erstellt. Es kann sowohl über eine grafische Oberfläche als auch über die Kommandozeile verwendet werden.
|
||||
|
||||
## Installation
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo apt update && sudo apt install timeshift
|
||||
|
||||
# Arch Linux
|
||||
sudo pacman -S timeshift
|
||||
|
||||
# Fedora/CentOS
|
||||
sudo dnf install timeshift
|
||||
```
|
||||
|
||||
## Grundlegende Konfiguration
|
||||
|
||||
### Initialisierung
|
||||
```bash
|
||||
# Timeshift einrichten (wählt automatisch RSYNC oder BTRFS)
|
||||
sudo timeshift --check
|
||||
|
||||
# Konfiguration anzeigen
|
||||
sudo timeshift --list-config
|
||||
```
|
||||
|
||||
### Backup-Typ festlegen
|
||||
```bash
|
||||
# RSYNC-Modus (Standard für ext4)
|
||||
sudo timeshift --rsync
|
||||
|
||||
# BTRFS-Modus (für BTRFS-Dateisysteme)
|
||||
sudo timeshift --btrfs
|
||||
```
|
||||
|
||||
## Snapshots erstellen
|
||||
|
||||
### Manuellen Snapshot erstellen
|
||||
```bash
|
||||
# Einfacher Snapshot
|
||||
sudo timeshift --create
|
||||
|
||||
# Snapshot mit Kommentar
|
||||
sudo timeshift --create --comments "Vor System-Update"
|
||||
|
||||
# Snapshot mit spezifischem Namen
|
||||
sudo timeshift --create --comments "Pre-Kernel-Update-$(date +%Y%m%d)"
|
||||
```
|
||||
|
||||
### Automatische Snapshots konfigurieren
|
||||
```bash
|
||||
# Tägliche Snapshots aktivieren
|
||||
sudo timeshift --snapshot-device /dev/sda1 --schedule-daily
|
||||
|
||||
# Wöchentliche Snapshots
|
||||
sudo timeshift --schedule-weekly
|
||||
|
||||
# Monatliche Snapshots
|
||||
sudo timeshift --schedule-monthly
|
||||
```
|
||||
|
||||
## Snapshots verwalten
|
||||
|
||||
### Snapshots auflisten
|
||||
```bash
|
||||
# Alle verfügbaren Snapshots anzeigen
|
||||
sudo timeshift --list
|
||||
|
||||
# Detaillierte Liste
|
||||
sudo timeshift --list --verbose
|
||||
```
|
||||
|
||||
### Snapshot-Informationen anzeigen
|
||||
```bash
|
||||
# Informationen zu einem spezifischen Snapshot
|
||||
sudo timeshift --list | grep "2024-01-15"
|
||||
```
|
||||
|
||||
## System wiederherstellen
|
||||
|
||||
### Komplette Systemwiederherstellung
|
||||
```bash
|
||||
# Neuesten Snapshot wiederherstellen
|
||||
sudo timeshift --restore
|
||||
|
||||
# Spezifischen Snapshot wiederherstellen
|
||||
sudo timeshift --restore --snapshot "2024-01-15_18-30-45"
|
||||
|
||||
# Wiederherstellung mit Bestätigung
|
||||
sudo timeshift --restore --snapshot "2024-01-15_18-30-45" --skip-grub
|
||||
```
|
||||
|
||||
### Einzelne Dateien wiederherstellen
|
||||
```bash
|
||||
# Snapshot mounten (nur-lesen)
|
||||
sudo timeshift --restore --snapshot "2024-01-15_18-30-45" --clone
|
||||
|
||||
# Dann Dateien manuell kopieren
|
||||
cp /timeshift/snapshots/2024-01-15_18-30-45/localhost/path/to/file /original/path/
|
||||
```
|
||||
|
||||
## TTY-Sitzung (Notfall-Wiederherstellung)
|
||||
|
||||
### Zugang zur TTY
|
||||
```bash
|
||||
# Wechsel zu TTY (Strg+Alt+F1 bis F6)
|
||||
# Oder über SSH wenn verfügbar
|
||||
```
|
||||
|
||||
### Wiederherstellung in TTY
|
||||
```bash
|
||||
# 1. Als root anmelden
|
||||
sudo su -
|
||||
|
||||
# 2. Snapshots auflisten
|
||||
timeshift --list
|
||||
|
||||
# 3. System wiederherstellen
|
||||
timeshift --restore --snapshot "SNAPSHOT_NAME"
|
||||
|
||||
# 4. System neustarten
|
||||
reboot
|
||||
```
|
||||
|
||||
### Notfall-Boot von Live-USB
|
||||
```bash
|
||||
# 1. Live-USB booten
|
||||
# 2. Festplatte mounten
|
||||
sudo mount /dev/sda1 /mnt
|
||||
|
||||
# 3. Timeshift auf Live-System installieren
|
||||
sudo apt update && sudo apt install timeshift
|
||||
|
||||
# 4. Wiederherstellung auf gemountete Partition
|
||||
sudo timeshift --restore --target-device /dev/sda1
|
||||
```
|
||||
|
||||
## Nützliche Optionen
|
||||
|
||||
### Backup-Ausschlüsse konfigurieren
|
||||
```bash
|
||||
# Bestimmte Verzeichnisse ausschließen
|
||||
sudo timeshift --exclude /home/user/Downloads
|
||||
sudo timeshift --exclude /tmp
|
||||
sudo timeshift --exclude /var/cache
|
||||
```
|
||||
|
||||
### Aufbewahrungsrichtlinien
|
||||
```bash
|
||||
# Maximale Anzahl Snapshots begrenzen
|
||||
sudo timeshift --max-snapshots 5
|
||||
|
||||
# Alte Snapshots automatisch löschen
|
||||
sudo timeshift --delete-old
|
||||
```
|
||||
|
||||
### Snapshot löschen
|
||||
```bash
|
||||
# Spezifischen Snapshot löschen
|
||||
sudo timeshift --delete --snapshot "2024-01-15_18-30-45"
|
||||
|
||||
# Alle bis auf die letzten 3 löschen
|
||||
sudo timeshift --delete-old --max-snapshots 3
|
||||
```
|
||||
|
||||
## Automatisierung mit Cron
|
||||
|
||||
### Tägliche Backups einrichten
|
||||
```bash
|
||||
# Crontab bearbeiten
|
||||
sudo crontab -e
|
||||
|
||||
# Tägliches Backup um 2:00 Uhr
|
||||
0 2 * * * /usr/bin/timeshift --create --comments "Daily-Auto-$(date +\%Y\%m\%d)" && /usr/bin/timeshift --delete-old --max-snapshots 7
|
||||
```
|
||||
|
||||
## Monitoring und Logs
|
||||
|
||||
### Status überprüfen
|
||||
```bash
|
||||
# Timeshift-Status
|
||||
sudo timeshift --check
|
||||
|
||||
# Logs anzeigen
|
||||
sudo journalctl -u timeshift
|
||||
tail -f /var/log/timeshift.log
|
||||
```
|
||||
|
||||
### Speicherplatz überwachen
|
||||
```bash
|
||||
# Snapshot-Größen anzeigen
|
||||
du -sh /timeshift/snapshots/*
|
||||
|
||||
# Verfügbaren Speicher prüfen
|
||||
df -h /timeshift
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Häufige Probleme
|
||||
```bash
|
||||
# Berechtigungen reparieren
|
||||
sudo timeshift --check
|
||||
|
||||
# Cache leeren
|
||||
sudo rm -rf /tmp/timeshift*
|
||||
|
||||
# Snapshot-Index reparieren
|
||||
sudo timeshift --delete-old --scripted
|
||||
```
|
||||
|
||||
### Recovery bei korrupten Snapshots
|
||||
```bash
|
||||
# Snapshot-Konsistenz prüfen
|
||||
sudo timeshift --list --check-snapshots
|
||||
|
||||
# Defekte Snapshots entfernen
|
||||
sudo timeshift --delete --snapshot "CORRUPT_SNAPSHOT"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Wichtige Hinweise:**
|
||||
- Immer mit `sudo` ausführen
|
||||
- Vor wichtigen Systemänderungen Snapshots erstellen
|
||||
- Regelmäßig alte Snapshots löschen (Speicherplatz)
|
||||
- Bei BTRFS-Systemen BTRFS-Modus verwenden
|
||||
- Boot-Snapshots für kritische Updates erstellen
|
||||
@@ -0,0 +1,111 @@
|
||||
Diese Anleitung zeigt, wie du einen USB-Stick über die Kommandozeile sicher formatierst.
|
||||
⚠️ **Achtung:** Falsche Gerätenamen können zu Datenverlust führen.
|
||||
|
||||
---
|
||||
|
||||
## 1. USB-Stick identifizieren
|
||||
|
||||
Liste alle Laufwerke auf:
|
||||
|
||||
```bash
|
||||
lsblk
|
||||
```
|
||||
|
||||
Beispielausgabe:
|
||||
|
||||
```
|
||||
sda 500G
|
||||
sdb 16G ← USB-Stick
|
||||
```
|
||||
|
||||
> **Merke dir den Gerätenamen des USB-Sticks**, z. B. `/dev/sdb`.
|
||||
|
||||
---
|
||||
|
||||
## 2. USB-Stick aushängen
|
||||
|
||||
Falls der Stick automatisch eingehängt wurde:
|
||||
|
||||
```bash
|
||||
sudo umount /dev/sdb*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Optional: Stick vollständig säubern
|
||||
|
||||
Entfernt alte Partitionstabellen:
|
||||
|
||||
```bash
|
||||
sudo wipefs -a /dev/sdb
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Neue Partitionstabelle anlegen (MBR)
|
||||
|
||||
```bash
|
||||
sudo parted /dev/sdb mklabel msdos
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Eine neue Partition über den gesamten Stick erstellen
|
||||
|
||||
```bash
|
||||
sudo parted -a optimal /dev/sdb mkpart primary fat32 0% 100%
|
||||
```
|
||||
|
||||
> Wenn du ein anderes Dateisystem planst, kannst du `fat32` durch einen anderen Typ ersetzen (z. B. `ext4`).
|
||||
|
||||
---
|
||||
|
||||
## 6. Dateisystem erstellen
|
||||
|
||||
### FAT32 (am kompatibelsten)
|
||||
|
||||
```bash
|
||||
sudo mkfs.vfat -F 32 /dev/sdb1
|
||||
```
|
||||
|
||||
### exFAT
|
||||
|
||||
```bash
|
||||
sudo mkfs.exfat /dev/sdb1
|
||||
```
|
||||
|
||||
### NTFS
|
||||
|
||||
```bash
|
||||
sudo mkfs.ntfs -Q /dev/sdb1
|
||||
```
|
||||
|
||||
### ext4 (für Linux-Systeme)
|
||||
|
||||
```bash
|
||||
sudo mkfs.ext4 /dev/sdb1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Stick entfernen und neu verbinden
|
||||
|
||||
Der Stick wird beim Wiedereinstecken normalerweise automatisch eingehängt.
|
||||
|
||||
---
|
||||
|
||||
## 8. Optional: Label setzen
|
||||
|
||||
```bash
|
||||
sudo fatlabel /dev/sdb1 MEINUSB
|
||||
```
|
||||
|
||||
Für ext4:
|
||||
|
||||
```bash
|
||||
sudo e2label /dev/sdb1 MEINUSB
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Wenn du möchtest, erstelle ich dir auch eine Version als **Obsidian-Template**, z. B. mit Variablen oder Checkboxen.
|
||||
@@ -0,0 +1,458 @@
|
||||
Hier ist ein kompaktes, aber vollständiges **VIM Cheat Sheet** 📝
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Modi in VIM
|
||||
|
||||
|Modus|Bedeutung|Wechsel|
|
||||
|---|---|---|
|
||||
|**Normal Mode**|Navigation & Befehle|`Esc`|
|
||||
|**Insert Mode**|Texteingabe|`i`, `a`, `o`, etc.|
|
||||
|**Visual Mode**|Text markieren|`v`, `V`, `Ctrl+v`|
|
||||
|**Command Mode**|Speichern, Beenden, etc.|`:`|
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Insert Mode Befehle
|
||||
|
||||
|Befehl|Wirkung|
|
||||
|---|---|
|
||||
|`i`|Vor Cursor einfügen|
|
||||
|`a`|Nach Cursor einfügen|
|
||||
|`I`|Am Zeilenanfang einfügen|
|
||||
|`A`|Am Zeilenende einfügen|
|
||||
|`o`|Neue Zeile unterhalb|
|
||||
|`O`|Neue Zeile oberhalb|
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Navigation (Normal Mode)
|
||||
|
||||
### Zeichenweise
|
||||
|
||||
```
|
||||
h ← j ↓ k ↑ l →
|
||||
```
|
||||
|
||||
### Wortweise
|
||||
|
||||
```
|
||||
w nächstes Wort
|
||||
b vorheriges Wort
|
||||
e Wortende
|
||||
```
|
||||
|
||||
### Zeilenweise
|
||||
|
||||
```
|
||||
0 Zeilenanfang
|
||||
^ Erstes Nicht-Leerzeichen
|
||||
$ Zeilenende
|
||||
```
|
||||
|
||||
### Datei
|
||||
|
||||
```
|
||||
gg Anfang der Datei
|
||||
G Ende der Datei
|
||||
:n Gehe zu Zeile n
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Löschen
|
||||
|
||||
|Befehl|Wirkung|
|
||||
|---|---|
|
||||
|`x`|Zeichen löschen|
|
||||
|`dd`|Zeile löschen|
|
||||
|`dw`|Wort löschen|
|
||||
|`d$`|Bis Zeilenende löschen|
|
||||
|`d0`|Bis Zeilenanfang löschen|
|
||||
|
||||
💡 Kombination: `d` + Bewegung funktioniert immer
|
||||
(z.B. `d3w` = 3 Wörter löschen)
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Kopieren & Einfügen
|
||||
|
||||
|Befehl|Wirkung|
|
||||
|---|---|
|
||||
|`yy`|Zeile kopieren|
|
||||
|`yw`|Wort kopieren|
|
||||
|`p`|Nach Cursor einfügen|
|
||||
|`P`|Vor Cursor einfügen|
|
||||
|
||||
#### Register
|
||||
Vor alle Kopieren oder Einfügen Befehle kann ein `"3` gestellt werden, um ins 3. Register zu schreiben bzw. daraus heraus zu lesen. Z.b. kopiert `"7yw` das Wort ins 7. Register und `"4p` fügt das 4. Register nach dem Curser ein.
|
||||
💡 Das spezielle Register `+`/`*` ist das System-Clipboard, sehr Praktisch zum Austausch von Text mit anderen Programmen
|
||||
Alle Register ansehen: `:reg`
|
||||
💡 Das spezielle Register `%` enthält den aktuellen Dateipfad -> aktuelle Dateipfad in System-Clipboard: `:let @+=@%`.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Undo / Redo
|
||||
|
||||
```
|
||||
u Undo
|
||||
Ctrl+r Redo
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Visual Mode
|
||||
|
||||
|Befehl|Wirkung|
|
||||
|---|---|
|
||||
|`v`|Zeichenweise markieren|
|
||||
|`V`|Ganze Zeile markieren|
|
||||
|`Ctrl+v`|Block markieren|
|
||||
|
||||
Nach Markierung:
|
||||
|
||||
```
|
||||
d löschen
|
||||
y kopieren
|
||||
> einrücken
|
||||
< ausrücken
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Suchen & Ersetzen
|
||||
|
||||
```
|
||||
/text Vorwärts suchen
|
||||
?text Rückwärts suchen
|
||||
n Nächstes Ergebnis
|
||||
N Vorheriges Ergebnis
|
||||
```
|
||||
|
||||
Ersetzen:
|
||||
|
||||
```
|
||||
:%s/alt/neu/g Ganze Datei
|
||||
:s/alt/neu/g Aktuelle Zeile
|
||||
:%s/alt/neu/gc Mit Bestätigung
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Speichern & Beenden
|
||||
|
||||
```
|
||||
:w Speichern
|
||||
:q Beenden
|
||||
:wq Speichern & Beenden
|
||||
:x Speichern & Beenden
|
||||
:q! Ohne Speichern beenden
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Fenster & Tabs
|
||||
|
||||
```
|
||||
:split Horizontal teilen
|
||||
:vsplit Vertikal teilen
|
||||
Ctrl+w w Zwischen Fenstern wechseln
|
||||
:tabnew Neuer Tab
|
||||
gt Nächster Tab
|
||||
gT Vorheriger Tab
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Nützliche Shortcuts
|
||||
|
||||
```
|
||||
. Letzte Aktion wiederholen
|
||||
>> Zeile einrücken
|
||||
<< Zeile ausrücken
|
||||
ciw Wort ändern
|
||||
cc Zeile ändern
|
||||
J Zeilen zusammenführen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Makros
|
||||
|
||||
```
|
||||
qa Aufnahme in Register a starten
|
||||
q Aufnahme stoppen
|
||||
@a Makro a ausführen
|
||||
@@ Letztes Makro wiederholen
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Zahlen-Präfixe (Sehr wichtig!)
|
||||
|
||||
Viele Befehle lassen sich multiplizieren:
|
||||
|
||||
```
|
||||
3dd 3 Zeilen löschen
|
||||
5w 5 Wörter vor
|
||||
2yy 2 Zeilen kopieren
|
||||
```
|
||||
|
||||
---
|
||||
# Zeilennummern aus- und anschalten
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Absolute Zeilennummern
|
||||
|
||||
### Einschalten:
|
||||
|
||||
```vim
|
||||
:set number
|
||||
```
|
||||
|
||||
### Ausschalten:
|
||||
|
||||
```vim
|
||||
:set nonumber
|
||||
```
|
||||
|
||||
### Toggle:
|
||||
|
||||
```vim
|
||||
:set number!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Relative Zeilennummern
|
||||
|
||||
### Einschalten:
|
||||
|
||||
```vim
|
||||
:set relativenumber
|
||||
```
|
||||
|
||||
### Ausschalten:
|
||||
|
||||
```vim
|
||||
:set norelativenumber
|
||||
```
|
||||
|
||||
### Toggle:
|
||||
|
||||
```vim
|
||||
:set relativenumber!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Absolute + Relative kombinieren (Sehr beliebt 🔥)
|
||||
|
||||
Viele nutzen diese Kombination:
|
||||
|
||||
```vim
|
||||
:set number relativenumber
|
||||
```
|
||||
|
||||
👉 Ergebnis:
|
||||
|
||||
* Aktuelle Zeile = **absolute Nummer**
|
||||
* Alle anderen Zeilen = **relative Nummern**
|
||||
|
||||
Beispiel:
|
||||
|
||||
```
|
||||
8
|
||||
2
|
||||
1
|
||||
10 ← aktuelle Zeile
|
||||
1
|
||||
2
|
||||
3
|
||||
```
|
||||
|
||||
Das ist perfekt für Bewegungen wie:
|
||||
|
||||
```
|
||||
5j
|
||||
3k
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Dauerhaft aktivieren (.vimrc)
|
||||
|
||||
In deiner `~/.vimrc`:
|
||||
|
||||
```vim
|
||||
set number
|
||||
set relativenumber
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Smart Toggle Mapping (Optional ⭐)
|
||||
|
||||
Viele nutzen ein Keybinding:
|
||||
|
||||
```vim
|
||||
nnoremap <leader>n :set number! relativenumber!<CR>
|
||||
```
|
||||
|
||||
Dann kannst du mit:
|
||||
|
||||
```
|
||||
\ n
|
||||
```
|
||||
|
||||
(beim Standard-`leader`) beide gleichzeitig toggeln.
|
||||
|
||||
---
|
||||
|
||||
|
||||
# Block Aus- und Einkommentieren
|
||||
|
||||
---
|
||||
|
||||
# 🔹 1️⃣ Rein mit Vim (ohne Plugin)
|
||||
|
||||
## ✅ Ganze Zeilen im Visual Mode kommentieren
|
||||
|
||||
### Schritt 1: Block markieren
|
||||
|
||||
* `V` → Zeilenweise markieren
|
||||
* `j / k` → Bereich wählen
|
||||
|
||||
### Schritt 2: Kommentarzeichen einfügen
|
||||
|
||||
Beispiel für `#`:
|
||||
|
||||
```vim
|
||||
:s/^/# /
|
||||
```
|
||||
|
||||
Im Visual Mode einfach:
|
||||
|
||||
```vim
|
||||
:'<,'>s/^/# /
|
||||
```
|
||||
|
||||
👉 Fügt `# ` am Anfang jeder markierten Zeile ein.
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Auskommentieren
|
||||
|
||||
```vim
|
||||
:'<,'>s/^# //
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Noch schneller (ohne `:` tippen)
|
||||
|
||||
Markieren mit `V`, dann:
|
||||
|
||||
```vim
|
||||
:s/^/# /
|
||||
```
|
||||
|
||||
Vim setzt `'<,'>` automatisch.
|
||||
|
||||
---
|
||||
|
||||
# 🔹 2️⃣ Noch effizienter: Visual Block Mode (Sehr elegant ⚡)
|
||||
|
||||
Perfekt für feste Kommentarzeichen wie `#`, `//`, `--`.
|
||||
|
||||
### Schritt 1
|
||||
|
||||
```
|
||||
Ctrl + v
|
||||
```
|
||||
|
||||
### Schritt 2
|
||||
|
||||
Mit `j/k` mehrere Zeilen markieren (nur Spalte 0)
|
||||
|
||||
### Schritt 3
|
||||
|
||||
```
|
||||
Shift + i
|
||||
#
|
||||
Esc
|
||||
```
|
||||
|
||||
💥 Vim fügt das in alle markierten Zeilen ein.
|
||||
|
||||
---
|
||||
|
||||
## 🔹 Entfernen mit Block Mode
|
||||
|
||||
1. `Ctrl + v`
|
||||
2. Erste 2 Zeichen (`# `) markieren
|
||||
3. `d`
|
||||
|
||||
---
|
||||
|
||||
# 🔹 3️⃣ Beste Lösung: Plugin (Empfohlen 🔥)
|
||||
|
||||
Wenn du regelmäßig kommentierst → nimm ein Plugin.
|
||||
|
||||
Sehr beliebt:
|
||||
|
||||
* vim-commentary von Tim Pope
|
||||
|
||||
### Installation (mit vim-plug):
|
||||
|
||||
```vim
|
||||
Plug 'tpope/vim-commentary'
|
||||
```
|
||||
|
||||
### Nutzung:
|
||||
|
||||
* `gcc` → aktuelle Zeile toggeln
|
||||
* `gc` (im Visual Mode) → Block toggeln
|
||||
|
||||
💎 Vorteil:
|
||||
|
||||
* erkennt automatisch Kommentarzeichen je nach Dateityp
|
||||
* funktioniert mit `//`, `#`, `--`, `/* */`, etc.
|
||||
|
||||
---
|
||||
|
||||
# 🔹 4️⃣ Absolute Power-User Lösung (Ohne Plugin, aber smart)
|
||||
|
||||
In `.vimrc`:
|
||||
|
||||
```vim
|
||||
vnoremap <leader>c :s/^/# /<CR>
|
||||
vnoremap <leader>u :s/^# //<CR>
|
||||
```
|
||||
|
||||
Dann:
|
||||
|
||||
```
|
||||
\c → kommentieren
|
||||
\u → auskommentieren
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 🔥 Meine Empfehlung
|
||||
|
||||
| Wenn du... | Lösung |
|
||||
| ----------------------------- | ----------------- |
|
||||
| Nur selten kommentierst | Visual Block Mode |
|
||||
| Viel programmierst | vim-commentary |
|
||||
| Minimalistisch bleiben willst | eigenes Mapping |
|
||||
|
||||
---
|
||||
# Verschiedenes
|
||||
- `%`: zur nächsten Klammer
|
||||
- `TOhtml`: HTML Export
|
||||
- `:ls`: Buffer anzeigen -> `:b 3` den 3. Buffer öffnen
|
||||
- `.` : letzte Aktion wiederholen
|
||||
- `:e path/to/file` öffnet Datei, nur `:e` aktualisiert die geöffnete Datei, `:e!` verwirft dabei alle Änderungen
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
# Anleitung: Windows-Programme unter Linux mit **Wine** in einer eigenen Umgebung installieren
|
||||
|
||||
Diese Anleitung zeigt dir, wie du **Windows-Programme unter Linux mithilfe von Wine** installierst – **pro Programm in einer eigenen isolierten Wine-Umgebung (Wineprefix)**.
|
||||
Die Schritte funktionieren unter den meisten Linux-Distributionen (Ubuntu, Fedora, Arch, etc.).
|
||||
|
||||
---
|
||||
|
||||
## ⭐ Grundbegriffe
|
||||
|
||||
### **Wine**
|
||||
Wine ist eine Kompatibilitätsschicht, die Windows-Programme unter Linux ausführen kann.
|
||||
|
||||
### **Wineprefix**
|
||||
Ein *Wineprefix* ist eine Art eigener Windows-Ordner (inkl. Registry, Laufwerke, DLLs).
|
||||
Standard: `~/.wine` – wir nutzen jedoch **pro Programm einen eigenen Prefix**, z. B.:
|
||||
|
||||
```
|
||||
|
||||
~/wineprefixes/MeinProgramm
|
||||
|
||||
````
|
||||
|
||||
Das verhindert Konflikte zwischen Programmen.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Voraussetzungen
|
||||
|
||||
### Wine & Winetricks installieren
|
||||
|
||||
**Ubuntu/Debian**
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install wine winetricks
|
||||
````
|
||||
|
||||
**Fedora**
|
||||
|
||||
```bash
|
||||
sudo dnf install wine winetricks
|
||||
```
|
||||
|
||||
**Arch Linux / Manjaro**
|
||||
|
||||
```bash
|
||||
sudo pacman -S wine winetricks
|
||||
```
|
||||
|
||||
> Optional: Für bessere Kompatibilität empfiehlt sich _winehq-staging_.
|
||||
|
||||
---
|
||||
|
||||
## 📁 1. Eigenen Wineprefix anlegen
|
||||
|
||||
Ersetze `<PROGRAMMNAME>` durch den gewünschten Namen.
|
||||
|
||||
```bash
|
||||
export WINEPREFIX="$HOME/wineprefixes/<PROGRAMMNAME>"
|
||||
wineboot --init
|
||||
```
|
||||
|
||||
Ordnerstruktur anlegen (falls noch nicht vorhanden):
|
||||
|
||||
```bash
|
||||
mkdir -p "$HOME/wineprefixes"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧩 2. Architektur festlegen (32- oder 64-bit)
|
||||
|
||||
### 32-bit Prefix (für ältere Programme empfohlen)
|
||||
|
||||
```bash
|
||||
export WINEARCH=win32
|
||||
export WINEPREFIX="$HOME/wineprefixes/<PROGRAMMNAME>"
|
||||
wineboot --init
|
||||
```
|
||||
|
||||
### 64-bit Prefix
|
||||
|
||||
```bash
|
||||
export WINEARCH=win64
|
||||
export WINEPREFIX="$HOME/wineprefixes/<PROGRAMMNAME>"
|
||||
wineboot --init
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧰 3. Prefix konfigurieren (optional)
|
||||
|
||||
### Wine-Konfiguration starten
|
||||
|
||||
```bash
|
||||
export WINEPREFIX="$HOME/wineprefixes/<PROGRAMMNAME>"
|
||||
winecfg
|
||||
```
|
||||
|
||||
Hier kannst du z. B. einstellen:
|
||||
|
||||
- Windows-Version (Win7, Win10, Win11)
|
||||
|
||||
- Grafikoptionen
|
||||
|
||||
- Audiotreiber
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 📦 4. Winetricks nutzen (DLLs, Fonts, Komponenten)
|
||||
|
||||
Beispiel: .NET 4.8 & corefonts installieren:
|
||||
|
||||
```bash
|
||||
export WINEPREFIX="$HOME/wineprefixes/<PROGRAMMNAME>"
|
||||
winetricks dotnet48 corefonts
|
||||
```
|
||||
|
||||
Winetricks GUI öffnen:
|
||||
|
||||
```bash
|
||||
winetricks --gui
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📥 5. Windows-Programm installieren
|
||||
|
||||
Beispiel mit einer `setup.exe`:
|
||||
|
||||
```bash
|
||||
export WINEPREFIX="$HOME/wineprefixes/<PROGRAMMNAME>"
|
||||
wine ~/Downloads/setup.exe
|
||||
```
|
||||
|
||||
Installer wie gewohnt durchklicken.
|
||||
|
||||
---
|
||||
|
||||
## ▶️ 6. Programm starten
|
||||
|
||||
Wenn das Programm z. B. `Programm.exe` heißt:
|
||||
|
||||
```bash
|
||||
export WINEPREFIX="$HOME/wineprefixes/<PROGRAMMNAME>"
|
||||
wine "$WINEPREFIX/drive_c/Program Files/<Hersteller>/<Programm>/Programm.exe"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📌 7. Starter (Desktop-Shortcut) erstellen
|
||||
|
||||
Erstelle eine Datei:
|
||||
|
||||
```
|
||||
~/.local/share/applications/<programm>.desktop
|
||||
```
|
||||
|
||||
Inhalt:
|
||||
|
||||
```desktop
|
||||
[Desktop Entry]
|
||||
Name=<PROGRAMMNAME>
|
||||
Exec=env WINEPREFIX="/home/$USER/wineprefixes/<PROGRAMMNAME>" wine "C:/Program Files/<Hersteller>/<Programm>/Programm.exe"
|
||||
Type=Application
|
||||
Categories=Utility;
|
||||
```
|
||||
|
||||
Datei ausführbar machen:
|
||||
|
||||
```bash
|
||||
chmod +x ~/.local/share/applications/<programm>.desktop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧼 8. Prefix entfernen
|
||||
|
||||
Wenn du das Programm löschen möchtest:
|
||||
|
||||
```bash
|
||||
rm -rf "$HOME/wineprefixes/<PROGRAMMNAME>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Zusatz: Nützliche Tools
|
||||
|
||||
### Wine Logs anzeigen
|
||||
|
||||
```bash
|
||||
WINEPREFIX="$HOME/wineprefixes/<PROGRAMMNAME>" wine Programm.exe &> log.txt
|
||||
```
|
||||
|
||||
### Abhängigkeiten prüfen
|
||||
|
||||
```bash
|
||||
winetricks dlls list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Tipps & Best Practices
|
||||
|
||||
- **Jedes Programm bekommt seinen eigenen Prefix** → weniger Konflikte.
|
||||
|
||||
- Für Spiele: **Lutris** oder **Bottles** nutzen.
|
||||
|
||||
- Für Office-Software häufig nötig: `dotnet48`, `corefonts`, `vcrun2015`.
|
||||
|
||||
- Falls ein Programm Probleme macht:
|
||||
→ WineHQ AppDB durchsuchen (Kompatibilitätsdatenbank).
|
||||
|
||||
|
||||
---
|
||||
|
||||
## ✔️ Zusammenfassung
|
||||
|
||||
1. Wine & Winetricks installieren
|
||||
|
||||
2. Eigenen Prefix erstellen
|
||||
|
||||
3. Architektur festlegen (32/64 bit)
|
||||
|
||||
4. Wine konfigurieren
|
||||
|
||||
5. Benötigte Komponenten via Winetricks installieren
|
||||
|
||||
6. Setup des Programms ausführen
|
||||
|
||||
7. Starter optional erstellen
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
# 🧭 Übersicht: `/etc/fstab` – Netzlaufwerke & SSHFS
|
||||
|
||||
Diese Datei enthält Einträge für automatisch eingehängte Netzlaufwerke.
|
||||
Wichtig: Teste Änderungen **immer** mit
|
||||
```bash
|
||||
sudo mount -a
|
||||
```
|
||||
um Syntaxfehler zu erkennen, bevor du neustartest.
|
||||
→ siehe [[fstab Grundlagen]]
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ NAS-Laufwerke via NFS
|
||||
|
||||
```fstab
|
||||
192.168.0.14:/volume1/Gemeinsam /mnt/nas/gemeinsam nfs nfsvers=3,rw,_netdev,noac,actimeo=0 0 0
|
||||
```
|
||||
|
||||
**Annahmen:**
|
||||
- NAS-IP: `192.168.0.14`
|
||||
- Freigabe (Quelle): `/volume1/Gemeinsam`
|
||||
- Lokaler Mountpoint (Ziel): `/mnt/nas/gemeinsam`
|
||||
|
||||
**Erläuterung der Optionen:**
|
||||
- `nfsvers=3` → nutzt NFSv3 (älter, aber oft stabiler bei Synology)
|
||||
- `rw` → Schreib-/Lesezugriff
|
||||
- `_netdev` → mountet erst, wenn Netzwerk verfügbar ist
|
||||
- `noac` → deaktiviert Client-Caching (nützlich bei Dateisynchronisierung, kann Performance senken)
|
||||
- `actimeo=0` → setzt Cache-Timeout auf 0 (Dateiattribute werden immer neu gelesen)
|
||||
|
||||
👉 siehe [[NFS unter Linux]] und [[NFS Mount Optionen]]
|
||||
|
||||
💡 *Tipp:*
|
||||
Bei neueren Systemen oder stabilen Netzwerken ist `nfsvers=4` meist die bessere Wahl. Beispiel:
|
||||
```fstab
|
||||
192.168.0.14:/volume1/Gemeinsam /mnt/nas/gemeinsam nfs nfsvers=4,rw,_netdev 0 0
|
||||
```
|
||||
|
||||
📦 **Benötigtes Paket (Debian/Ubuntu):**
|
||||
```bash
|
||||
sudo apt install nfs-common
|
||||
```
|
||||
→ siehe [[NFS Client Installation]]
|
||||
|
||||
---
|
||||
|
||||
## ☁️ HiDrive via SFTP (SSHFS)
|
||||
|
||||
```fstab
|
||||
mathias2784@sftp.hidrive.strato.com:/users/mathias2784 /mnt/hidrive fuse.sshfs defaults,_netdev,IdentityFile=/home/mathias/.ssh/id_ed25519,allow_other 0 0
|
||||
```
|
||||
|
||||
**Erläuterung der Optionen:**
|
||||
- `fuse.sshfs` → nutzt das FUSE-Modul für SSHFS
|
||||
- `_netdev` → warte auf Netzwerk
|
||||
- `IdentityFile=...` → Pfad zum SSH-Key
|
||||
- `allow_other` → erlaubt Zugriff auch für andere Nutzer (Achtung: [[SSHFS Sicherheit]])
|
||||
|
||||
👉 siehe [[SSHFS unter Linux]] und [[HiDrive Konfiguration]]
|
||||
|
||||
💡 *Tipp:*
|
||||
Füge optional `reconnect,ServerAliveInterval=15,ServerAliveCountMax=3` hinzu, damit die Verbindung stabil bleibt:
|
||||
```fstab
|
||||
mathias2784@sftp.hidrive.strato.com:/users/mathias2784 /mnt/hidrive fuse.sshfs _netdev,IdentityFile=/home/mathias/.ssh/id_ed25519,allow_other,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 0 0
|
||||
```
|
||||
|
||||
📦 **Benötigtes Paket (Debian/Ubuntu):**
|
||||
```bash
|
||||
sudo apt install sshfs
|
||||
```
|
||||
→ siehe [[SSHFS Installation]]
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ "Schneiderserver" via SSHFS
|
||||
|
||||
```fstab
|
||||
root@schneiderserver.site:/root /mnt/strato_vm fuse.sshfs _netdev,IdentityFile=/home/mathias/.ssh/id_ed25519_strato_vm,allow_other 0 0
|
||||
```
|
||||
|
||||
**Optionen wie oben**, jedoch:
|
||||
- Zugriff als `root` nur wenn zwingend notwendig (besser: Benutzer mit begrenzten Rechten)
|
||||
- Key-File ggf. mit restriktiven Rechten (`chmod 600`)
|
||||
|
||||
👉 siehe [[SSH Sicherheit]] und [[Root via SSH vermeiden]]
|
||||
|
||||
📦 **Benötigtes Paket (Debian/Ubuntu):**
|
||||
```bash
|
||||
sudo apt install sshfs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Allgemeine Hinweise
|
||||
|
||||
- Testen: `sudo mount -a`
|
||||
- Mounten einzelner Einträge:
|
||||
```bash
|
||||
sudo mount /mnt/hidrive
|
||||
```
|
||||
- Logs prüfen bei Problemen:
|
||||
```bash
|
||||
sudo journalctl -xe | grep sshfs
|
||||
```
|
||||
|
||||
Weitere Themen: [[fstab Optionen Übersicht]], [[Mount Fehlerbehebung]], [[Systemd Automounts]]
|
||||
@@ -0,0 +1,479 @@
|
||||
# Snapper Anleitung für CachyOS - Detaillierte Version
|
||||
|
||||
## Was ist Snapper?
|
||||
|
||||
Snapper ist ein Tool für BTRFS-Dateisysteme, das automatisch Snapshots (Momentaufnahmen) erstellt. Diese Snapshots sind wie "Wiederherstellungspunkte" - sie speichern den Zustand deines Systems zu einem bestimmten Zeitpunkt, ohne zusätzlichen Speicherplatz für unveränderte Dateien zu verbrauchen.
|
||||
|
||||
## Installation mit pacman
|
||||
|
||||
```bash
|
||||
# Hauptpakete installieren
|
||||
sudo pacman -S snapper # Das eigentliche Snapper-Tool
|
||||
sudo pacman -S snap-pac # Automatische Snapshots bei pacman-Operationen
|
||||
sudo pacman -S snapper-gui-git # Grafische Benutzeroberfläche (optional)
|
||||
|
||||
# Optional: Für GRUB-Integration (Boot-Menü mit Snapshots)
|
||||
sudo pacman -S grub-btrfs # Zeigt Snapshots im GRUB-Boot-Menü an
|
||||
```
|
||||
|
||||
## Grundkonfiguration verstehen
|
||||
|
||||
### 1. Snapper-Konfiguration für Root erstellen
|
||||
|
||||
```bash
|
||||
# Falls bereits eine Konfiguration existiert, diese entfernen
|
||||
sudo umount /.snapshots 2>/dev/null || true
|
||||
sudo rm -rf /.snapshots
|
||||
|
||||
# Neue Snapper-Konfiguration für das Root-Dateisystem erstellen
|
||||
# Dies erstellt automatisch eine Konfigurationsdatei unter /etc/snapper/configs/root
|
||||
sudo snapper -c root create-config /
|
||||
|
||||
# Das automatisch erstellte .snapshots Verzeichnis ist ein normaler Ordner
|
||||
# Wir brauchen aber ein BTRFS-Subvolume für bessere Performance
|
||||
sudo btrfs subvolume delete /.snapshots
|
||||
sudo mkdir /.snapshots
|
||||
|
||||
# Subvolume in /etc/fstab eintragen (wird automatisch gemacht)
|
||||
sudo mount -a
|
||||
```
|
||||
|
||||
**Was passiert hier?**
|
||||
- `-c root` = Konfigurationsname "root"
|
||||
- `create-config /` = Erstelle Konfiguration für das Verzeichnis `/`
|
||||
- Ein BTRFS-Subvolume ist effizienter als ein normaler Ordner für Snapshots
|
||||
|
||||
### 2. Konfigurationsdatei im Detail
|
||||
|
||||
```bash
|
||||
sudo nano /etc/snapper/configs/root
|
||||
```
|
||||
|
||||
**Wichtige Parameter erklärt:**
|
||||
|
||||
```ini
|
||||
# SUBVOLUME: Das zu überwachende Verzeichnis
|
||||
SUBVOLUME="/"
|
||||
|
||||
# FSTYPE: Dateisystemtyp (muss btrfs sein)
|
||||
FSTYPE="btrfs"
|
||||
|
||||
# ALLOW_USERS/ALLOW_GROUPS: Welche Benutzer dürfen Snapshots verwalten?
|
||||
ALLOW_USERS="dein-benutzername"
|
||||
ALLOW_GROUPS="wheel"
|
||||
|
||||
# SYNC_ACL: Access Control Lists synchronisieren
|
||||
SYNC_ACL="no"
|
||||
|
||||
# === TIMELINE SNAPSHOTS (zeitbasierte automatische Snapshots) ===
|
||||
|
||||
# TIMELINE_CREATE: Sollen automatische zeitbasierte Snapshots erstellt werden?
|
||||
TIMELINE_CREATE="yes"
|
||||
|
||||
# TIMELINE_CLEANUP: Sollen alte Timeline-Snapshots automatisch gelöscht werden?
|
||||
TIMELINE_CLEANUP="yes"
|
||||
|
||||
# Wie viele Timeline-Snapshots sollen behalten werden?
|
||||
TIMELINE_MIN_AGE="1800" # Mindestens 30 Minuten alt bevor Löschung möglich
|
||||
TIMELINE_LIMIT_HOURLY="10" # Maximal 10 stündliche Snapshots
|
||||
TIMELINE_LIMIT_DAILY="10" # Maximal 10 tägliche Snapshots
|
||||
TIMELINE_LIMIT_WEEKLY="0" # Keine wöchentlichen Snapshots
|
||||
TIMELINE_LIMIT_MONTHLY="10" # Maximal 10 monatliche Snapshots
|
||||
TIMELINE_LIMIT_YEARLY="10" # Maximal 10 jährliche Snapshots
|
||||
|
||||
# === NUMBER CLEANUP (Bereinigung nach Anzahl) ===
|
||||
|
||||
# NUMBER_CLEANUP: Snapshots nach Anzahl begrenzen?
|
||||
NUMBER_CLEANUP="yes"
|
||||
|
||||
# NUMBER_MIN_AGE: Snapshots müssen mindestens so alt sein (Sekunden)
|
||||
NUMBER_MIN_AGE="1800" # 30 Minuten
|
||||
|
||||
# NUMBER_LIMIT: Maximale Gesamtanzahl an Snapshots
|
||||
NUMBER_LIMIT="50"
|
||||
|
||||
# NUMBER_LIMIT_IMPORTANT: Wichtige Snapshots (pre/post) getrennt begrenzen
|
||||
NUMBER_LIMIT_IMPORTANT="10"
|
||||
|
||||
# === EMPTY CLEANUP (leere Snapshots löschen) ===
|
||||
EMPTY_PRE_POST_CLEANUP="yes" # Leere Pre/Post-Snapshot-Paare löschen
|
||||
EMPTY_PRE_POST_MIN_AGE="1800"
|
||||
```
|
||||
|
||||
**Was bedeuten die verschiedenen Snapshot-Typen?**
|
||||
- **Timeline**: Automatisch nach Zeit erstellt (stündlich, täglich, etc.)
|
||||
- **Pre/Post**: Vor und nach Systemänderungen (z.B. Package-Updates)
|
||||
- **Single**: Einzelne manuelle Snapshots
|
||||
|
||||
## Ein- und Ausgeschlossene Verzeichnisse verstehen
|
||||
|
||||
### Automatisch eingeschlossene Verzeichnisse
|
||||
|
||||
Standardmäßig wird **alles unter `/` gesnappt**, außer:
|
||||
|
||||
```bash
|
||||
# Diese Verzeichnisse werden NIEMALS gesnappt (hardcoded in Snapper):
|
||||
/dev/* # Device-Dateien (virtuelle Dateien)
|
||||
/proc/* # Process-Informationen (virtuelle Dateien)
|
||||
/sys/* # System-Informationen (virtuelle Dateien)
|
||||
/tmp/* # Temporäre Dateien
|
||||
/run/* # Runtime-Daten
|
||||
/mnt/* # Mount-Punkte
|
||||
/media/* # Wechseldatenträger
|
||||
```
|
||||
|
||||
### Zusätzliche Ausschlüsse konfigurieren
|
||||
|
||||
**Option 1: Exclude-Patterns in der Hauptkonfiguration**
|
||||
|
||||
```bash
|
||||
sudo nano /etc/snapper/configs/root
|
||||
```
|
||||
|
||||
Füge hinzu:
|
||||
```ini
|
||||
# EXCLUDE_PATTERNS: Glob-Patterns für auszuschließende Dateien/Ordner
|
||||
EXCLUDE_PATTERNS="/var/cache/* /var/tmp/* /var/log/* /home/*/.cache/* /root/.cache/*"
|
||||
```
|
||||
|
||||
**Option 2: Separate Filter-Datei (empfohlen)**
|
||||
|
||||
```bash
|
||||
# Filter-Datei erstellen
|
||||
sudo mkdir -p /etc/snapper/filters
|
||||
sudo nano /etc/snapper/filters/root.txt
|
||||
```
|
||||
|
||||
Inhalt mit Erklärungen:
|
||||
```bash
|
||||
# Cache-Verzeichnisse (können jederzeit neu erstellt werden)
|
||||
/var/cache/*
|
||||
/home/*/.cache/*
|
||||
/root/.cache/*
|
||||
|
||||
# Temporäre Dateien
|
||||
/var/tmp/*
|
||||
/tmp/*
|
||||
|
||||
# Log-Dateien (werden laufend überschrieben, Snapshots wenig sinnvoll)
|
||||
/var/log/*
|
||||
|
||||
# Browser-Profile (sehr große, häufig ändernde Dateien)
|
||||
/home/*/.mozilla/firefox/*/Cache/*
|
||||
/home/*/.config/google-chrome/Default/Cache/*
|
||||
|
||||
# Papierkorb
|
||||
/home/*/.local/share/Trash/*
|
||||
|
||||
# Downloads (optional - je nach Bedarf)
|
||||
# /home/*/Downloads/*
|
||||
|
||||
# Virtuelle Maschinen (sehr groß)
|
||||
/home/*/.local/share/libvirt/*
|
||||
/var/lib/libvirt/*
|
||||
|
||||
# Docker-Daten (sehr groß und dynamisch)
|
||||
/var/lib/docker/*
|
||||
```
|
||||
|
||||
Dann in der Hauptkonfiguration referenzieren:
|
||||
```ini
|
||||
# In /etc/snapper/configs/root hinzufügen:
|
||||
EXCLUDE_FILE="/etc/snapper/filters/root.txt"
|
||||
```
|
||||
|
||||
### Warum diese Ausschlüsse?
|
||||
|
||||
- **Cache-Verzeichnisse**: Werden automatisch neu erstellt, verschwenden nur Platz
|
||||
- **Log-Dateien**: Ändern sich ständig, Snapshots helfen nicht bei der Fehlersuche
|
||||
- **Temporäre Dateien**: Per Definition temporär
|
||||
- **Browser-Caches**: Riesig und unwichtig für System-Recovery
|
||||
- **VM/Docker-Daten**: Sehr groß, haben eigene Backup-Strategien
|
||||
|
||||
## Manuelle Snapshots erstellen
|
||||
|
||||
### Einfache Snapshots
|
||||
|
||||
```bash
|
||||
# Einfacher Snapshot mit Beschreibung
|
||||
sudo snapper -c root create -d "Vor Firefox-Installation"
|
||||
|
||||
# Snapshot mit benutzerdefinierten Attributen
|
||||
sudo snapper -c root create -d "Backup vor Kernel-Update" -u "important=yes"
|
||||
```
|
||||
|
||||
### Pre/Post-Snapshot-Paare (empfohlen für größere Änderungen)
|
||||
|
||||
```bash
|
||||
# 1. PRE-Snapshot erstellen (vor der Änderung)
|
||||
sudo snapper -c root create -t pre -p -d "Vor großem System-Update"
|
||||
# Merke dir die Nummer! Z.B. "42"
|
||||
|
||||
# 2. Deine Systemänderungen durchführen
|
||||
sudo pacman -Syu
|
||||
|
||||
# 3. POST-Snapshot erstellen (nach der Änderung)
|
||||
sudo snapper -c root create -t post --pre-number 42 -d "Nach großem System-Update"
|
||||
```
|
||||
|
||||
**Warum Pre/Post-Paare?**
|
||||
- Snapper kann exakt die Unterschiede zwischen vorher/nachher zeigen
|
||||
- Einfacheres Rollback nur der Änderungen
|
||||
- Bessere Übersicht was sich geändert hat
|
||||
|
||||
### Snapshots verwalten
|
||||
|
||||
```bash
|
||||
# Alle Snapshots auflisten
|
||||
sudo snapper -c root list
|
||||
|
||||
# Detaillierte Ansicht mit Größe
|
||||
sudo snapper -c root list -t all
|
||||
|
||||
# Informationen zu einem bestimmten Snapshot
|
||||
sudo snapper -c root info 42
|
||||
|
||||
# Unterschiede zwischen zwei Snapshots anzeigen
|
||||
sudo snapper -c root status 40..45
|
||||
|
||||
# Geänderte Dateien zwischen Snapshots zeigen
|
||||
sudo snapper -c root diff 40..45
|
||||
```
|
||||
|
||||
## Automatisierung der Snapshot-Erstellung
|
||||
|
||||
### 1. Timeline-Snapshots (zeitbasiert)
|
||||
|
||||
```bash
|
||||
# Systemd-Timer für stündliche Timeline-Snapshots aktivieren
|
||||
sudo systemctl enable --now snapper-timeline.timer
|
||||
|
||||
# Timer für automatische Bereinigung alter Snapshots aktivieren
|
||||
sudo systemctl enable --now snapper-cleanup.timer
|
||||
|
||||
# Status der Timer prüfen
|
||||
systemctl status snapper-timeline.timer
|
||||
systemctl status snapper-cleanup.timer
|
||||
|
||||
# Nächste geplante Ausführung anzeigen
|
||||
systemctl list-timers | grep snapper
|
||||
```
|
||||
|
||||
**Was macht snapper-timeline.timer?**
|
||||
- Läuft stündlich
|
||||
- Erstellt automatisch Timeline-Snapshots basierend auf der Konfiguration
|
||||
- Berücksichtigt die TIMELINE_LIMIT-Einstellungen
|
||||
|
||||
**Was macht snapper-cleanup.timer?**
|
||||
- Läuft täglich
|
||||
- Löscht alte Snapshots basierend auf den Cleanup-Regeln
|
||||
- Verhindert, dass das System mit Snapshots volläuft
|
||||
|
||||
### 2. Automatische Snapshots bei Package-Updates
|
||||
|
||||
Das Paket `snap-pac` erstellt automatisch Pre/Post-Snapshots bei jeder pacman-Operation.
|
||||
|
||||
```bash
|
||||
# Konfiguration von snap-pac anpassen
|
||||
sudo nano /etc/snap-pac.ini
|
||||
```
|
||||
|
||||
```ini
|
||||
[DEFAULT]
|
||||
# Maximale Länge der Snapshot-Beschreibung
|
||||
desc_limit = 72
|
||||
|
||||
# Standard-Beschreibungen für automatische Snapshots
|
||||
pre_description = pacman pre snapshot
|
||||
post_description = pacman post snapshot
|
||||
|
||||
# Soll snap-pac auch bei AUR-Helper-Updates Snapshots erstellen?
|
||||
aur_helper = yay,paru,pikaur
|
||||
|
||||
[root]
|
||||
# Snapshots für das root-Subvolume aktivieren
|
||||
snapshot = yes
|
||||
|
||||
# Welche Cleanup-Strategie verwenden?
|
||||
cleanup = number
|
||||
|
||||
# Soll snap-pac auch bei normalen pacman-Operationen (nicht nur -S) Snapshots erstellen?
|
||||
important = yes
|
||||
```
|
||||
|
||||
**Was passiert jetzt?**
|
||||
- Bei jedem `sudo pacman -S paket` → automatisches Pre/Post-Snapshot-Paar
|
||||
- Bei `yay -S aur-paket` → ebenfalls Snapshots (wenn konfiguriert)
|
||||
- Bei `sudo pacman -R paket` → ebenfalls Snapshots
|
||||
|
||||
### 3. GRUB-Integration für Boot-Menü
|
||||
|
||||
```bash
|
||||
# GRUB-Btrfs-Daemon aktivieren (überwacht Snapshot-Änderungen)
|
||||
sudo systemctl enable --now grub-btrfsd
|
||||
|
||||
# Initramfs-Hook für Snapshot-Booting hinzufügen
|
||||
sudo nano /etc/mkinitcpio.conf
|
||||
```
|
||||
|
||||
In der HOOKS-Zeile hinzufügen:
|
||||
```bash
|
||||
HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block filesystems grub-btrfs-overlayfs fsck)
|
||||
```
|
||||
|
||||
```bash
|
||||
# Initramfs neu generieren
|
||||
sudo mkinitcpio -P
|
||||
|
||||
# GRUB-Konfiguration aktualisieren
|
||||
sudo grub-mkconfig -o /boot/grub/grub.cfg
|
||||
```
|
||||
|
||||
**Was bringt das?**
|
||||
- Im GRUB-Boot-Menü erscheint ein neuer Eintrag "Snapshots for GNU/Linux"
|
||||
- Du kannst direkt von einem Snapshot booten ohne das System zu ändern
|
||||
- Perfekt um zu testen, ob ein älterer Zustand das Problem löst
|
||||
|
||||
## Snapshots wiederherstellen
|
||||
|
||||
### 1. Einzelne Dateien wiederherstellen
|
||||
|
||||
```bash
|
||||
# Snapshot mounten (macht ihn als Verzeichnis verfügbar)
|
||||
sudo snapper -c root mount 42
|
||||
|
||||
# Jetzt ist der Snapshot verfügbar unter:
|
||||
# /.snapshots/42/snapshot/
|
||||
|
||||
# Beispiel: Konfigurationsdatei wiederherstellen
|
||||
sudo cp /.snapshots/42/snapshot/etc/fstab /etc/fstab
|
||||
|
||||
# Beispiel: Ganzes Verzeichnis wiederherstellen
|
||||
sudo cp -r /.snapshots/42/snapshot/etc/NetworkManager/ /etc/
|
||||
|
||||
# Snapshot wieder unmounten (Speicher freigeben)
|
||||
sudo snapper -c root umount 42
|
||||
```
|
||||
|
||||
### 2. Änderungen zwischen Snapshots rückgängig machen
|
||||
|
||||
```bash
|
||||
# Zeige was sich zwischen zwei Snapshots geändert hat
|
||||
sudo snapper -c root status 40..45
|
||||
|
||||
# Mache alle Änderungen zwischen den Snapshots rückgängig
|
||||
sudo snapper -c root undochange 40..45
|
||||
|
||||
# Alternativ: Rollback zu einem bestimmten Snapshot
|
||||
sudo snapper -c root rollback 42
|
||||
```
|
||||
|
||||
**Vorsicht bei undochange:**
|
||||
- Überschreibt aktuelle Dateien!
|
||||
- Erstelle vorher einen aktuellen Snapshot als Backup
|
||||
- Teste erst in einer nicht-kritischen Umgebung
|
||||
|
||||
### 3. Komplettes System-Rollback (für Experten)
|
||||
|
||||
```bash
|
||||
# ACHTUNG: Dies überschreibt dein aktuelles System!
|
||||
# Erstelle erst einen Snapshot des aktuellen Zustands
|
||||
sudo snapper -c root create -d "Vor Rollback - Notfall-Backup"
|
||||
|
||||
# Zeige verfügbare Snapshots
|
||||
sudo snapper -c root list
|
||||
|
||||
# Rollback zu Snapshot (z.B. Nummer 42)
|
||||
sudo btrfs subvolume snapshot /.snapshots/42/snapshot /
|
||||
```
|
||||
|
||||
### 4. Boot von Snapshot über GRUB
|
||||
|
||||
Wenn grub-btrfs installiert ist:
|
||||
|
||||
1. **Computer neu starten**
|
||||
2. **Im GRUB-Menü**: "Snapshots for GNU/Linux" wählen
|
||||
3. **Snapshot auswählen**: Den gewünschten Snapshot aus der Liste wählen
|
||||
4. **System startet** vom gewählten Snapshot (read-only)
|
||||
5. **Wenn alles funktioniert**: `sudo snapper rollback` um permanent zu wechseln
|
||||
|
||||
## Überwachung und Wartung
|
||||
|
||||
### Speicherplatz überwachen
|
||||
|
||||
```bash
|
||||
# BTRFS-Dateisystem-Nutzung anzeigen
|
||||
sudo btrfs filesystem usage /
|
||||
|
||||
# Größe aller Snapshots anzeigen
|
||||
sudo btrfs subvolume list / | grep snapshots
|
||||
|
||||
# Detaillierte Snapshot-Größen
|
||||
for snap in $(sudo snapper -c root list | tail -n +3 | awk '{print $1}'); do
|
||||
if [ "$snap" != "0" ]; then
|
||||
size=$(sudo btrfs subvolume show "/.snapshots/$snap/snapshot" 2>/dev/null | grep -E "^\s*Gen:" | wc -l)
|
||||
echo "Snapshot $snap: Exists"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
### Automatische Bereinigung konfigurieren
|
||||
|
||||
```bash
|
||||
# Manuelle Bereinigung ausführen
|
||||
sudo snapper -c root cleanup number # Nach Anzahl-Regeln
|
||||
sudo snapper -c root cleanup timeline # Nach Zeit-Regeln
|
||||
|
||||
# Bereinigung-Logs anzeigen
|
||||
journalctl -u snapper-cleanup.service
|
||||
```
|
||||
|
||||
## Fehlerbehandlung und Tipps
|
||||
|
||||
### Häufige Probleme
|
||||
|
||||
**Problem**: `/.snapshots` ist ein normaler Ordner, kein Subvolume
|
||||
```bash
|
||||
# Lösung:
|
||||
sudo umount /.snapshots
|
||||
sudo rm -rf /.snapshots
|
||||
sudo btrfs subvolume create /.snapshots
|
||||
sudo systemctl restart snapper-timeline.timer
|
||||
```
|
||||
|
||||
**Problem**: Snapshots verbrauchen zu viel Speicher
|
||||
```bash
|
||||
# Lösung: Bereinigungsregeln anpassen
|
||||
sudo nano /etc/snapper/configs/root
|
||||
# NUMBER_LIMIT reduzieren (z.B. auf 20)
|
||||
# Mehr Ausschlüsse hinzufügen
|
||||
```
|
||||
|
||||
**Problem**: Automatische Snapshots funktionieren nicht
|
||||
```bash
|
||||
# Debugging:
|
||||
systemctl status snapper-timeline.timer
|
||||
journalctl -u snapper-timeline.service
|
||||
sudo snapper -c root create -d "Test" # Manuell testen
|
||||
```
|
||||
|
||||
### Best Practices
|
||||
|
||||
1. **Vor großen Änderungen**: Immer manuelles Pre/Post-Snapshot-Paar
|
||||
2. **Regelmäßige Kontrolle**: `sudo snapper list` alle paar Tage prüfen
|
||||
3. **Speicherplatz überwachen**: Bei >80% Festplattenbelegung Snapshots reduzieren
|
||||
4. **Test-Rollbacks**: Erst in VM oder Testsystem ausprobieren
|
||||
5. **Backup-Strategie**: Snapper ersetzt keine externe Datensicherung!
|
||||
6. **Wichtige Daten**: Separat in `/home` mit eigenem Snapshot-Schema verwalten
|
||||
|
||||
### Erweiterte Konfiguration für /home
|
||||
|
||||
```bash
|
||||
# Separate Snapshot-Konfiguration für Home-Verzeichnis
|
||||
sudo snapper -c home create-config /home
|
||||
|
||||
# Andere Bereinigungsregeln für /home (mehr Snapshots, da wichtiger)
|
||||
sudo nano /etc/snapper/configs/home
|
||||
```
|
||||
|
||||
Diese detaillierte Anleitung sollte dir ein vollständiges Verständnis von Snapper und dessen Konfiguration geben!
|
||||
Reference in New Issue
Block a user