#!/bin/bash

## Einfaches Beispielskript, dass Listen erzeugt mit den installierten 
## Paketen und Anwendungen erzeugt. Siehe c’t 13/2022, S. 132, ct.de/ys1f
## Entweder in Cron eintragen oder vom Backup-Programm vor dem Start
## eines Backup aufrufen.

## Ort, wo die Listen abgelegt werden sollen. Nach Bedarf anpassen.
## Die ~ steht für das Home-Verzeichnis des aufrufenden Users. Also
## beim User cttest wäre es /home/cttest. Bei Unsicherheit absolute
## Pfade angeben. Verzeichnis muss vorhanden sein. 
## Beispiele
## LISTDIR=~
## LISTDIR=~/Backups
## LISTDIR=~/Backups/Paketlisten

LISTDIR=~

## Debian, Ubuntu, Linux Mint usw.
## Listen mit apt erzeugen.
APT_LIST=yes

## Fedora, Red Hat usw. (nicht openSUSE)
## Listen mit dnf erzeugen.
DNF_LIST=yes

## Arch Linux, Manjaro usw.
## Listen mit pacman erzeugen.
PACMAN_LIST=yes

## Snap, insbesondere bei Ubuntu
SNAP_LIST=yes

## Flatpak, wenn z.B. Flathub genutzt wird.
FLATPAK_LIST=yes

## Neue Datei für jeden Aufruf anlegen?
## yes - Datei apt.list, flatpak.list, snap.list wird überschrieben
## no  - Datei mit Datum wird angelegt z.B. apt_2022-05-24-09-44-30.list
## Default no 
OVERWRITE_FILE=no

## Wird das Skript zweimal in exakt der gleichen Sekunde aufgerufen, wird
## die eine Datei auch bei "no" überschrieben.

# Hilfvariablen leer initialisieren
NAME=""
BINARY=""

# Prüfung, ob Verzeichnis vorhanden und schreibbar
if [ -z ${LISTDIR} ]; then
	echo "Fehler: Kein Verzeichnis angegeben. Abbruch."
	exit 1
elif [ ! -d $LISTDIR ]; then
	echo "Fehler: Verzeichnis ${LISTDIR} nicht vorhanden. Abbruch."
	exit 1
elif [ ! -w $LISTDIR ]; then
	echo "Fehler: Keine Schreibrechte für Verzeichnis ${LISTDIR}. Abbruch."
	exit 1
else
	echo "Erzeuge Listen installierter Pakete und Apps"
	
	if [ "$OVERWRITE_FILE" == "yes" ]; then
		echo "Überschreibe vorhandene Dateien."
		FILENAME_SUFFIX=".list"
	else
		DATE=`date +"%F-%H-%M-%S"`
		FILENAME_SUFFIX="_${DATE}.list"
	fi
## Liste der manuell installierten Pakete…
	## Debian, Ubuntu, Linux Mint etc. 
	# apt list --manual-installed

	## apt, Paketmanager für Debian, Ubuntu usw.
	if [ "$APT_LIST" == "yes" ]; then
		NAME=APT
		BINARY=apt
		if [ -z `command -v $BINARY` ]; then
			echo "Fehler: ${BINARY} nicht gefunden. Überspringe ${NAME}."
		else
			echo "Erzeuge $NAME-Liste…"
			FILENAME="${LISTDIR}/${BINARY}${FILENAME_SUFFIX}"
			
			apt list --manual-installed > $FILENAME
			
		fi
	fi	
	## Snap, App-Store von Ubuntu-Hersteller Canonical
	if [ "$SNAP_LIST" == "yes" ]; then
		NAME=SNAP
		BINARY=snap
		if [ -z `command -v $BINARY` ]; then
			echo "Fehler: ${BINARY} nicht gefunden. Überspringe ${NAME}."
		else
			echo "Erzeuge $NAME-Liste…"
			FILENAME="${LISTDIR}/${BINARY}${FILENAME_SUFFIX}"
			
			snap list > $FILENAME
			
		fi
	fi
	## Flatpak, unabhängiges Linux-Paketformat
	if [ "$FLATPAK_LIST" == "yes" ]; then
		NAME=Flatpak
		BINARY=flatpak
		if [ -z `command -v $BINARY` ]; then
			echo "Fehler: ${BINARY} nicht gefunden. Überspringe ${NAME}."
		else
			echo "Erzeuge $NAME-Liste…"
			FILENAME="${LISTDIR}/${BINARY}${FILENAME_SUFFIX}"
			
			flatpak list --app --columns=application,installation > $FILENAME
		fi
	fi
	
	## DNF, Paketmanager für Fedora
	if [ "$DNF_LIST" == "yes" ]; then
		NAME=DNF
		BINARY=dnf
		if [ -z `command -v $BINARY` ]; then
			echo "Fehler: ${BINARY} nicht gefunden. Überspringe ${NAME}."
		else
			echo "Erzeuge $NAME-Liste…"
			FILENAME="${LISTDIR}/${BINARY}${FILENAME_SUFFIX}"
			
			dnf history userinstalled > $FILENAME
		fi
	fi
	
	## Pacman, Paketmanager für Arch Linux
	if [ "$PACMAN_LIST" == "yes" ]; then
		NAME=Pacman
		BINARY=pacman
		if [ -z `command -v $BINARY` ]; then
			echo "Fehler: ${BINARY} nicht gefunden. Überspringe ${NAME}."
		else
			echo "Erzeuge $NAME-Liste…"
			FILENAME="${LISTDIR}/${BINARY}${FILENAME_SUFFIX}"
			
			pacman -Qet > $FILENAME
		fi
	fi

fi 
