v0.3.0: Pfeil-/Tab-Navigation gefixt, install/uninstall-Skripte
- FileTable(DataTable): links/rechts fuer Datei-Manager-Navigation umgebunden (links = eine Ebene hoch, rechts = Ordner oeffnen); zuvor verschluckte das DataTable-Widget die Tasten - _selected(): liefert jetzt die Klartext-Zeichenkette statt rich.Text-Objekt (behob AttributeError beim Oeffnen/Enter) - action_focus_next(): Tab wechselt zuverlaessig zwischen lokalem und entferntem Paneel (statt unzuverlaessigem focus_next) - install.sh / uninstall.sh: systemweite Installation (PEP-668-konform via /opt/ftptui/venv + /usr/local/bin/ftptui)
This commit is contained in:
@@ -95,6 +95,23 @@ pip install -e .
|
|||||||
# paramiko - SFTP/SSH
|
# paramiko - SFTP/SSH
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Installations- & Deinstallations-Skripte (systemweit)
|
||||||
|
|
||||||
|
Im Projektverzeichnis liegen zwei Scripts für eine **systemweite Installation**
|
||||||
|
auf Debian/Ubuntu (PEP 668 „externally managed“ wird berücksichtigt: es wird eine
|
||||||
|
eigene Umgebung unter `/opt/ftptui/venv` angelegt und nach
|
||||||
|
`/usr/local/bin/ftptui` verlinkt):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./install.sh # systemweit installieren (fragt ggf. nach sudo)
|
||||||
|
./install.sh --force # erneut installieren/aktualisieren
|
||||||
|
|
||||||
|
./uninstall.sh # systemweite Installation entfernen (Nutzdaten bleiben)
|
||||||
|
./uninstall.sh --purge # zusätzlich Konfigurationsdateien löschen
|
||||||
|
```
|
||||||
|
|
||||||
|
Nach `./install.sh` steht das Kommando `ftptui` global im PATH bereit.
|
||||||
|
|
||||||
### Als Paket
|
### Als Paket
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -142,8 +159,10 @@ ftptui
|
|||||||
| Taste | Aktion |
|
| Taste | Aktion |
|
||||||
|--------------|---------------------------------|
|
|--------------|---------------------------------|
|
||||||
| `Tab` | Zwischen lokalem und entferntem Paneel wechseln |
|
| `Tab` | Zwischen lokalem und entferntem Paneel wechseln |
|
||||||
| `Enter` | Ordner öffnen (aktiv: fokussiertes Paneel) |
|
| `↑` / `↓` | Zeilenauswahl bewegen |
|
||||||
|
| `→` | Markierten Ordner/Eintrag öffnen |
|
||||||
| `←` / `⌫` | Eine Verzeichnisebene höher |
|
| `←` / `⌫` | Eine Verzeichnisebene höher |
|
||||||
|
| `Enter` | Ordner öffnen (aktiv: fokussiertes Paneel) |
|
||||||
| `↑ ..` | Eine Ebene höher (Tabellenzeile) |
|
| `↑ ..` | Eine Ebene höher (Tabellenzeile) |
|
||||||
| `l` | Auswahl **herunterladen** (entfernt → lokal) |
|
| `l` | Auswahl **herunterladen** (entfernt → lokal) |
|
||||||
| `u` | Auswahl **hochladen** (lokal → entfernt) |
|
| `u` | Auswahl **hochladen** (lokal → entfernt) |
|
||||||
@@ -154,7 +173,8 @@ ftptui
|
|||||||
|
|
||||||
> Hinweis: Hoch-/Herunterladen (`u`/`l`), Anlegen (`n`), Löschen (`d`) und
|
> Hinweis: Hoch-/Herunterladen (`u`/`l`), Anlegen (`n`), Löschen (`d`) und
|
||||||
> Umbenennen (`r`) wirken auf das **aktive (grün markierte) Paneel**. Wechsel
|
> Umbenennen (`r`) wirken auf das **aktive (grün markierte) Paneel**. Wechsel
|
||||||
> der Seite mit `Tab`.
|
> der Seite mit `Tab`. Die Pfeiltasten `→`/`←` navigieren die Verzeichnisstruktur
|
||||||
|
> (öffnen / eine Ebene hoch), `↑`/`↓` bewegen die Zeilenauswahl.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -164,6 +184,8 @@ ftptui
|
|||||||
ftptui/
|
ftptui/
|
||||||
├── pyproject.toml # Paketmetadaten, Abhängigkeiten, Einstiegspunkt
|
├── pyproject.toml # Paketmetadaten, Abhängigkeiten, Einstiegspunkt
|
||||||
├── README.md # diese Dokumentation
|
├── README.md # diese Dokumentation
|
||||||
|
├── install.sh # systemweite Installation (/opt/ftptui/venv)
|
||||||
|
├── uninstall.sh # Deinstallation systemweiter Installation
|
||||||
├── .gitignore
|
├── .gitignore
|
||||||
└── ftptui/
|
└── ftptui/
|
||||||
├── __init__.py # Versionsnummer
|
├── __init__.py # Versionsnummer
|
||||||
@@ -305,6 +327,21 @@ MIT – siehe Projektträger/Repositories. Keine gewerblichen Einschränkungen.
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
### v0.3.0
|
||||||
|
- **Bugfix (Pfeil-Navigation):** Im Dateibrowser navigieren die Pfeiltasten nun
|
||||||
|
im File-Manager-Stil: `←` wechselt eine Ebene nach oben, `→` öffnet den
|
||||||
|
markierten Eintrag, `↑`/`↓` bewegen die Auswahl. Zuvor verschluckte das
|
||||||
|
`DataTable`-Widget die Tasten (Widget-Bindings haben Vorrang). Dafür wird die
|
||||||
|
neue `FileTable`-Klasse genutzt, die `left`/`right` passend umbindet.
|
||||||
|
- **Bugfix (Tab-Panel-Wechsel):** `Tab` wechselt jetzt zuverlässig zwischen dem
|
||||||
|
lokalen und dem entfernten Paneel (explizite `action_focus_next` statt
|
||||||
|
unzuverlässigem `focus_next`).
|
||||||
|
- **Bugfix (`_selected`):** Die Auswahlauswertung liefert jetzt die
|
||||||
|
Klartext-Zeichenkette statt eines `rich.Text`-Objekts, wodurch Öffnen/Enter
|
||||||
|
nicht mehr mit `AttributeError` abstürzte.
|
||||||
|
- **Neu:** `install.sh` / `uninstall.sh` für systemweite Installation
|
||||||
|
(PEP-668-konform via `/opt/ftptui/venv` + `/usr/local/bin/ftptui`).
|
||||||
|
|
||||||
### v0.2.0
|
### v0.2.0
|
||||||
- **Bugfix:** Wechsel in den Browser-Bildschirm korrigiert
|
- **Bugfix:** Wechsel in den Browser-Bildschirm korrigiert
|
||||||
(`set_screen` → `switch_screen`). Vorher führte eine erfolgreiche Verbindung
|
(`set_screen` → `switch_screen`). Vorher führte eine erfolgreiche Verbindung
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
"""ftptui - Interaktiver FTP/SFTP-Client als Terminal-User-Interface."""
|
"""ftptui - Interaktiver FTP/SFTP-Client als Terminal-User-Interface."""
|
||||||
|
|
||||||
__version__ = "0.2.0"
|
__version__ = "0.3.0"
|
||||||
|
|||||||
+44
-9
@@ -67,6 +67,28 @@ def _join(path: str, name: str, is_local: bool) -> str:
|
|||||||
return path.rstrip("/") + "/" + name
|
return path.rstrip("/") + "/" + name
|
||||||
|
|
||||||
|
|
||||||
|
class FileTable(DataTable):
|
||||||
|
"""DataTable mit Datei-Manager-Navigation.
|
||||||
|
|
||||||
|
``DataTable`` bindet die Pfeiltasten selbst (``left``/``right`` bewegen den
|
||||||
|
Cursor horizontal, was bei einer einzelnen Spalte sinnlos ist). Damit die
|
||||||
|
klassischen File-Manager-Bindings (Total Commander / ranger) funktionieren,
|
||||||
|
werden ``left``/``right`` hier auf „eine Ebene hoch“ bzw. „Ordner öffnen“
|
||||||
|
umgebunden. ``up``/``down`` bewegen weiterhin die Zeilenauswahl.
|
||||||
|
"""
|
||||||
|
|
||||||
|
BINDINGS = [
|
||||||
|
Binding("left", "up_level", "Eine Ebene hoch", priority=True, show=False),
|
||||||
|
Binding("right", "open_row", "Öffnen", priority=True, show=False),
|
||||||
|
]
|
||||||
|
|
||||||
|
def action_up_level(self) -> None:
|
||||||
|
self.screen.action_up_level()
|
||||||
|
|
||||||
|
def action_open_row(self) -> None:
|
||||||
|
self.screen.action_open()
|
||||||
|
|
||||||
|
|
||||||
class ConnectionScreen(Screen):
|
class ConnectionScreen(Screen):
|
||||||
"""Startbildschirm zur Eingabe der Verbindungsdaten (Terminal-Look)."""
|
"""Startbildschirm zur Eingabe der Verbindungsdaten (Terminal-Look)."""
|
||||||
|
|
||||||
@@ -191,7 +213,6 @@ class BrowserScreen(Screen):
|
|||||||
Binding("n", "mkdir", "Verzeichnis"),
|
Binding("n", "mkdir", "Verzeichnis"),
|
||||||
Binding("d", "delete", "Löschen"),
|
Binding("d", "delete", "Löschen"),
|
||||||
Binding("r", "rename", "Umbenennen"),
|
Binding("r", "rename", "Umbenennen"),
|
||||||
Binding("left", "up_level", "Eine Ebene hoch"),
|
|
||||||
Binding("backspace", "up_level", "Eine Ebene hoch"),
|
Binding("backspace", "up_level", "Eine Ebene hoch"),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -202,13 +223,13 @@ class BrowserScreen(Screen):
|
|||||||
yield Horizontal(
|
yield Horizontal(
|
||||||
Vertical(
|
Vertical(
|
||||||
Static(" Lokal ", classes="pane-title local-title active"),
|
Static(" Lokal ", classes="pane-title local-title active"),
|
||||||
DataTable(id="local_table"),
|
FileTable(id="local_table"),
|
||||||
classes="pane",
|
classes="pane",
|
||||||
),
|
),
|
||||||
Static(" ", classes="vsep"),
|
Static(" ", classes="vsep"),
|
||||||
Vertical(
|
Vertical(
|
||||||
Static(" Entfernt ", classes="pane-title remote-title"),
|
Static(" Entfernt ", classes="pane-title remote-title"),
|
||||||
DataTable(id="remote_table"),
|
FileTable(id="remote_table"),
|
||||||
classes="pane",
|
classes="pane",
|
||||||
),
|
),
|
||||||
classes="panes",
|
classes="panes",
|
||||||
@@ -228,13 +249,26 @@ class BrowserScreen(Screen):
|
|||||||
self._refresh_local()
|
self._refresh_local()
|
||||||
self._refresh_remote()
|
self._refresh_remote()
|
||||||
|
|
||||||
def _setup_table(self, table: DataTable) -> None:
|
def _setup_table(self, table: FileTable) -> None:
|
||||||
table.add_column("Name", key="name")
|
table.add_column("Name", key="name")
|
||||||
table.add_column("Größe", key="size")
|
table.add_column("Größe", key="size")
|
||||||
table.add_column("Datum", key="date")
|
table.add_column("Datum", key="date")
|
||||||
table.cursor_type = "row"
|
table.cursor_type = "row"
|
||||||
table.zebra_stripes = False
|
table.zebra_stripes = False
|
||||||
|
|
||||||
|
def action_focus_next(self) -> None:
|
||||||
|
"""Wechselt den Fokus direkt zwischen lokalem und entferntem Paneel.
|
||||||
|
|
||||||
|
``focus_next`` (das Standard-Tab-Verhalten) springt über alle fokussierbaren
|
||||||
|
Widgets und erreicht die zweite Tabelle nicht zuverlässig. Deshalb wird der
|
||||||
|
Fokus hier explizit auf die jeweils andere Tabelle gesetzt.
|
||||||
|
"""
|
||||||
|
if self.app.focused is self.table_local:
|
||||||
|
self.table_remote.focus()
|
||||||
|
else:
|
||||||
|
self.table_local.focus()
|
||||||
|
self._update_info()
|
||||||
|
|
||||||
def on_descendant_focus(self, event) -> None:
|
def on_descendant_focus(self, event) -> None:
|
||||||
if event.widget is self.table_local:
|
if event.widget is self.table_local:
|
||||||
self.query_one(".local-title", Static).add_class("active")
|
self.query_one(".local-title", Static).add_class("active")
|
||||||
@@ -304,22 +338,23 @@ class BrowserScreen(Screen):
|
|||||||
f"lokal: {self.local_path} | entfernt: {self.remote_path}"
|
f"lokal: {self.local_path} | entfernt: {self.remote_path}"
|
||||||
)
|
)
|
||||||
self.query_one("#statusbar", Static).update(
|
self.query_one("#statusbar", Static).update(
|
||||||
" F2/Tab Panele · Enter Öffnen · l Download · u Upload · "
|
" Tab Panele · ↑/↓ Auswahl · ← Hoch · → Öffnen · Enter Öffnen · "
|
||||||
"n Neu · d Löschen · r Umbenennen · ← Hoch · q Beenden"
|
"l Download · u Upload · n Neu · d Löschen · r Umbenennen · q Beenden"
|
||||||
)
|
)
|
||||||
|
|
||||||
@on(DataTable.RowHighlighted)
|
@on(DataTable.RowHighlighted)
|
||||||
def _highlight(self, event: DataTable.RowHighlighted) -> None:
|
def _highlight(self, event: DataTable.RowHighlighted) -> None:
|
||||||
self._update_info()
|
self._update_info()
|
||||||
|
|
||||||
def _focused_table(self) -> DataTable:
|
def _focused_table(self) -> FileTable:
|
||||||
return self.table_local if self.app.focused is self.table_local else self.table_remote
|
return self.table_local if self.app.focused is self.table_local else self.table_remote
|
||||||
|
|
||||||
def _selected(self, table: DataTable) -> str | None:
|
def _selected(self, table: FileTable) -> str | None:
|
||||||
row = table.cursor_row
|
row = table.cursor_row
|
||||||
if row is None:
|
if row is None:
|
||||||
return None
|
return None
|
||||||
return table.get_row_at(row)[0]
|
cell = table.get_row_at(row)[0]
|
||||||
|
return cell.plain if isinstance(cell, Text) else str(cell)
|
||||||
|
|
||||||
@on(DataTable.RowSelected, "#local_table")
|
@on(DataTable.RowSelected, "#local_table")
|
||||||
def _local_selected(self, event: DataTable.RowSelected) -> None:
|
def _local_selected(self, event: DataTable.RowSelected) -> None:
|
||||||
|
|||||||
Executable
+91
@@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# ftptui – Installations-Skript (systemweit)
|
||||||
|
#
|
||||||
|
# Das System nutzt ein "externally managed" Python (PEP 668, Debian/Ubuntu),
|
||||||
|
# daher wird NIE direkt in System-Site-Packages installiert. Stattdessen wird
|
||||||
|
# eine eigene systemweite virtuelle Umgebung unter /opt/ftptui/venv angelegt
|
||||||
|
# und der Einstiegspunkt nach /usr/local/bin/ftptui verlinkt. Damit steht das
|
||||||
|
# Kommando global im PATH, ohne das System-Python zu gefährden.
|
||||||
|
#
|
||||||
|
# Verwendung:
|
||||||
|
# ./install.sh # installiert systemweit (fragt ggf. nach sudo)
|
||||||
|
# ./install.sh --force # überschreibt eine bereits installierte Version
|
||||||
|
# ./install.sh --uninstall
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PACKAGE_DIR="$SCRIPT_DIR"
|
||||||
|
APP_NAME="ftptui"
|
||||||
|
VENV_DIR="/opt/ftptui/venv"
|
||||||
|
BIN_LINK="/usr/local/bin/$APP_NAME"
|
||||||
|
|
||||||
|
FORCE=0
|
||||||
|
MODE="install"
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--force|-f) FORCE=1 ;;
|
||||||
|
--uninstall|-u) MODE="uninstall" ;;
|
||||||
|
-h|--help) echo "Verwendung: $0 [--force|--uninstall]"; exit 0 ;;
|
||||||
|
*) echo "Unbekanntes Argument: $arg"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
run_sudo() {
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
"$@"
|
||||||
|
else
|
||||||
|
sudo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "$MODE" = "uninstall" ]; then
|
||||||
|
echo "==> Entferne systemweite Installation von '$APP_NAME' ..."
|
||||||
|
run_sudo rm -f "$BIN_LINK"
|
||||||
|
run_sudo rm -rf /opt/ftptui
|
||||||
|
echo "==> Entfernt: $BIN_LINK und $VENV_DIR"
|
||||||
|
echo "=> Fertig. (Konfigurationsdateien unter ~/.config/ftptui bleiben erhalten.)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> ftptui Installations-Skript (systemweit, via /opt/ftptui/venv)"
|
||||||
|
|
||||||
|
# Abhängigkeiten prüfen
|
||||||
|
command -v python3 >/dev/null 2>&1 || { echo "FEHLER: python3 nicht gefunden."; exit 1; }
|
||||||
|
if ! python3 -m venv --help >/dev/null 2>&1; then
|
||||||
|
echo "FEHLER: python3-venv fehlt. Bitte installieren: sudo apt install python3-venv"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Bereits installiert?
|
||||||
|
if [ -x "$BIN_LINK" ] && [ "$FORCE" -ne 1 ]; then
|
||||||
|
echo "WARNUNG: '$APP_NAME' ist bereits installiert: $BIN_LINK"
|
||||||
|
echo " Mit --force wird neu installiert."
|
||||||
|
echo " Zum Entfernen: $0 --uninstall (bzw. ./uninstall.sh)"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> Lege systemweite virtuelle Umgebung an: $VENV_DIR"
|
||||||
|
run_sudo python3 -m venv "$VENV_DIR"
|
||||||
|
run_sudo "$VENV_DIR/bin/pip" install --upgrade pip
|
||||||
|
|
||||||
|
echo "==> Installiere '$APP_NAME' + Abhängigkeiten ..."
|
||||||
|
run_sudo "$VENV_DIR/bin/pip" install --upgrade "$PACKAGE_DIR"
|
||||||
|
|
||||||
|
echo "==> Verlinke Einstiegspunkt nach $BIN_LINK"
|
||||||
|
run_sudo ln -sf "$VENV_DIR/bin/$APP_NAME" "$BIN_LINK"
|
||||||
|
|
||||||
|
# Konfigurationsverzeichnis anlegen
|
||||||
|
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/ftptui"
|
||||||
|
mkdir -p "$CONFIG_DIR"
|
||||||
|
echo "==> Konfigurationsverzeichnis bereit: $CONFIG_DIR"
|
||||||
|
|
||||||
|
# Fertig
|
||||||
|
echo
|
||||||
|
echo "Installation abgeschlossen."
|
||||||
|
echo " Befehl: $(command -v "$APP_NAME" 2>/dev/null || echo "$BIN_LINK")"
|
||||||
|
echo " Start: $APP_NAME"
|
||||||
|
echo " Venv: $VENV_DIR"
|
||||||
|
echo
|
||||||
|
echo "Tipp: 'ftptui' startet die TUI. Entfernen mit: ./uninstall.sh"
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "ftptui"
|
name = "ftptui"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
description = "Interaktiver FTP/SFTP-Client als Terminal-User-Interface in Python"
|
description = "Interaktiver FTP/SFTP-Client als Terminal-User-Interface in Python"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
|
|||||||
Executable
+61
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# ftptui – Deinstallations-Skript (systemweit)
|
||||||
|
#
|
||||||
|
# Entfernt die systemweite Installation (venv unter /opt/ftptui und den
|
||||||
|
# Einstiegspunkt /usr/local/bin/ftptui).
|
||||||
|
#
|
||||||
|
# Verwendung:
|
||||||
|
# ./uninstall.sh # entfernt das Paket (Nutzdaten bleiben)
|
||||||
|
# ./uninstall.sh --purge # entfernt zusätzlich die Konfigurationsdateien
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
APP_NAME="ftptui"
|
||||||
|
VENV_DIR="/opt/ftptui/venv"
|
||||||
|
BIN_LINK="/usr/local/bin/$APP_NAME"
|
||||||
|
|
||||||
|
PURGE=0
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--purge|-p) PURGE=1 ;;
|
||||||
|
-h|--help) echo "Verwendung: $0 [--purge]"; exit 0 ;;
|
||||||
|
*) echo "Unbekanntes Argument: $arg"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
run_sudo() {
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
"$@"
|
||||||
|
else
|
||||||
|
sudo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "==> ftptui Deinstallations-Skript"
|
||||||
|
|
||||||
|
if [ -x "$BIN_LINK" ] || [ -d "$VENV_DIR" ]; then
|
||||||
|
echo "==> Entferne systemweite Installation ..."
|
||||||
|
run_sudo rm -f "$BIN_LINK"
|
||||||
|
run_sudo rm -rf /opt/ftptui
|
||||||
|
echo "==> Entfernt: $BIN_LINK und $VENV_DIR"
|
||||||
|
else
|
||||||
|
echo "==> Keine systemweite Installation gefunden (kein $BIN_LINK / $VENV_DIR)."
|
||||||
|
fi
|
||||||
|
|
||||||
|
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/ftptui"
|
||||||
|
if [ "$PURGE" -eq 1 ]; then
|
||||||
|
if [ -e "$CONFIG_DIR" ]; then
|
||||||
|
rm -rf "$CONFIG_DIR"
|
||||||
|
echo "==> Konfigurationsverzeichnis entfernt: $CONFIG_DIR"
|
||||||
|
else
|
||||||
|
echo "==> Kein Konfigurationsverzeichnis gefunden."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "==> Nutzdaten (Verbindungsprofile) bleiben erhalten: $CONFIG_DIR"
|
||||||
|
echo " (mit --purge werden auch diese entfernt)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Deinstallation abgeschlossen."
|
||||||
Reference in New Issue
Block a user