Bevor ich mich in den Osterurlaub verabschiede, habe ich noch etwas zu sagen. Meine Vermutung war, dass ich bereits einen Artikel zu diesem Thema geschrieben habe, doch dem ist nicht so. Unsere Suchfunktion fördert nichts Passendes zutage. In meinen Aufzeichnungen (ZIM) habe ich Spurenelemente gefunden, die darauf hinweisen, dass ich mich bereits mit der Frage beschäftigt habe.
Angenommen, ihr verwendet in eurer Lieblingsdistribution mehrere Paketformate (DEB, RPM, Snap, Flatpak, AppImages oder was auch immer). Dann stellt sich manchmal die Frage, in welchem Format man eine bestimmte Anwendung installiert hat. Wer eine gute Paketverwaltung hat, kann diese nach den installierten Paketen befragen, und weiss dann, ob Firefox als natives Paket oder Gimp als Flatpak installiert ist. Selbst ohne eine umfassende Paketverwaltung lässt sich die Frage auf der Kommandozeile schnell klären.
Für meinen Geschmack ist das zu viel Klickibunti, bzw. sind es zu viele Befehle im Terminal. Ich habe nur eine Frage, auf die ich ohne Umwege eine Antwort haben möchte. Nennen wir den Befehl "pacform", der mir für eine Anwendung sagt, in welchem Paketformat (oder mehreren) die Anwendung bei mir installiert ist.
Vibe-Coding
Ja, ich schäme mich, habe ich doch ein LLM (Lumo) nach einer Lösung gefragt. Eigentlich sollte sich mein Notebook schämen, weil es vorhin nicht mehr aus der Bildschirm-Abdunklung aufgewacht ist und ich deshalb den KI-Prompt verloren habe. Da muss ich einmal die Energiespareinstellungen ändern, weil mir das schon ein paar Mal passiert ist. Oder sollte ich mich für den miserablen Code der KI schämen?
Der verlorene Prompt hiess ungefähr so:
Generiere ein Linux Shell-Skript, welches einen Paketnamen als Eingaben annimmt und mir ausgiebt, in welchen Paketformaten dieses Paket auf meinem Computer installiert ist. Berücksichtige alle relevanten nativen und Container-basierten Formate.
Das Ergebnis von Proton-Lumo sah so aus:
#!/bin/bash
# Package Search Script
# Searches for installed packages across multiple package managers
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Check if search term is provided
if [ $# -eq 0 ]; then
echo -e "${RED}Usage: $$0 $${NC}"
echo "Example: $0 firefox"
exit 1
fi
SEARCH_TERM="$1"
FOUND_ANY=false
echo -e "$${BLUE}========================================$${NC}"
echo -e "${BLUE}Searching for: $${GREEN}$$SEARCH_TERM${NC}"
echo -e "$${BLUE}========================================$${NC}"
echo ""
# Function to print section header
print_header() {
echo -e "${YELLOW}--- $$1 ---$${NC}"
}
# Function to print result
print_result() {
local format="$1"
local package="$2"
echo -e " $${GREEN}[$${format}]${NC} $package"
FOUND_ANY=true
}
# Function to print no results
print_no_results() {
echo -e " $${RED}No packages found$${NC}"
}
# ============================================
# DEB/APT (Debian, Ubuntu, Linux Mint, etc.)
# ============================================
if command -v dpkg &> /dev/null; then
print_header "DEB/APT Packages"
RESULTS=$$(dpkg -l 2>/dev/null | grep -i "$$SEARCH_TERM" | grep "^ii" || true)
if [ -n "$RESULTS" ]; then
echo "$RESULTS" | while read -r line; do
PACKAGE=$$(echo "$$line" | awk '{print $2}')
print_result "DEB" "$PACKAGE"
done
else
print_no_results
fi
echo ""
fi
# ============================================
# RPM (Red Hat, Fedora, CentOS, openSUSE, etc.)
# ============================================
if command -v rpm &> /dev/null; then
print_header "RPM Packages"
RESULTS=$$(rpm -qa 2>/dev/null | grep -i "$$SEARCH_TERM" || true)
if [ -n "$RESULTS" ]; then
echo "$RESULTS" | while read -r package; do
print_result "RPM" "$package"
done
else
print_no_results
fi
echo ""
fi
# ============================================
# Pacman (Arch Linux, Manjaro, etc.)
# ============================================
if command -v pacman &> /dev/null; then
print_header "Pacman (Arch) Packages"
RESULTS=$$(pacman -Q 2>/dev/null | grep -i "$$SEARCH_TERM" || true)
if [ -n "$RESULTS" ]; then
echo "$RESULTS" | while read -r line; do
PACKAGE=$$(echo "$$line" | awk '{print $1}')
print_result "ARCH" "$PACKAGE"
done
else
print_no_results
fi
echo ""
fi
# ============================================
# Snap (Universal package format)
# ============================================
if command -v snap &> /dev/null; then
print_header "Snap Packages"
RESULTS=$$(snap list 2>/dev/null | grep -i "$$SEARCH_TERM" || true)
if [ -n "$RESULTS" ]; then
echo "$RESULTS" | while read -r line; do
PACKAGE=$$(echo "$$line" | awk '{print $1}')
print_result "SNAP" "$PACKAGE"
done
else
print_no_results
fi
echo ""
fi
# ============================================
# Flatpak (Universal package format)
# ============================================
if command -v flatpak &> /dev/null; then
print_header "Flatpak Packages"
RESULTS=$$(flatpak list --app 2>/dev/null | grep -i "$$SEARCH_TERM" || true)
if [ -n "$RESULTS" ]; then
echo "$RESULTS" | while read -r line; do
PACKAGE=$$(echo "$$line" | awk '{print $1}')
print_result "FLATPAK" "$PACKAGE"
done
else
print_no_results
fi
echo ""
fi
# ============================================
# AppImage (Standalone executables)
# ============================================
print_header "AppImage Files"
FOUND_APPIMAGE=false
# Common locations for AppImages
APPIMAGE_DIRS=("$$HOME" "$$HOME/Applications" "/opt" "/usr/local/bin")
for dir in "${APPIMAGE_DIRS[@]}"; do
if [ -d "$dir" ]; then
RESULTS=$$(find "$$dir" -maxdepth 3 -name "*.AppImage" 2>/dev/null | grep -i "$SEARCH_TERM" || true)
if [ -n "$RESULTS" ]; then
echo "$RESULTS" | while read -r filepath; do
echo -e " $${GREEN}[AppImage]$${NC} $$(basename "$$filepath") ($filepath)"
FOUND_ANY=true
FOUND_APPIMAGE=true
done
fi
fi
done
if [ "$FOUND_APPIMAGE" = false ]; then
print_no_results
fi
echo ""
# ============================================
# Summary
# ============================================
echo -e "$${BLUE}========================================$${NC}"
if [ "$FOUND_ANY" = true ]; then
echo -e "$${GREEN}Search complete. Packages found!$${NC}"
else
echo -e "$${RED}Search complete. No packages found matching '$$SEARCH_TERM'${NC}"
fi
echo -e "$${BLUE}========================================$${NC}"
Auf den ersten Blick sieht es nett aus, aber:
- Aufgrund von Syntaxfehlern funktioniert es nicht
- Wegen der Redundanzen ist es viel zu lang
- Es enthält Funktionen, nach denen ich nicht gefragt habe (Farben)
Ralf-Coding
Da ich wenig Ahnung von Bash-Skripten habe und KI-generiertem Code grundsätzlich misstrauisch gegenüberstehe, habe ich mir den Code genau angesehen und nach einer Weile die oben genannten Missstände erkannt. Schlussendlich hat diese Überprüfung länger gedauert, als hätte ich das Skript in Python ohne KI-Hilfe geschrieben. Da ein Python-Skript zu viel für diese Kleinigkeit gewesen wäre, habe ich Einiges aus dem KI-generierten Code übernommen. So sieht mein Shell-Skript aus:
#!/bin/bash
# Searches for installed packages across multiple package managers
# Constants
# ==============================================================================
SEARCH_TERM="$1"
TAB=" "
# Check if search term is provided
# ==============================================================================
if [ $# -eq 0 ]; then
echo "No package name provided!"
echo "Example: $0 firefox"
exit 1
fi
# Print result of the package search
# ==============================================================================
print_result() {
if [ -n "$RESULT" ]; then
echo "$RESULT" | while read -r line; do
PACKAGE=$(echo "$line" | awk '{print $0}')
echo "$TAB" "$PACKAGE"
done
else
echo "$TAB" "No packages found"
fi
echo ""
}
# Arch (Manjaro, CachyOS, EndeavourOS, etc.)
# ==============================================================================
if command -v pacman &> /dev/null; then
echo "Arch"
RESULT=$(pacman -Q 2>/dev/null | grep -i "$SEARCH_TERM" || true)
print_result $RESULT
fi
# Flatpak
# ==============================================================================
if command -v flatpak &> /dev/null; then
echo "Flatpak"
RESULT=$(flatpak list --app 2>/dev/null | grep -i "$SEARCH_TERM" || true)
print_result $RESULT
fi
# DEB (Debian, Ubuntu, Linux Mint, etc.)
# ==============================================================================
if command -v dpkg &> /dev/null; then
echo "DEB"
RESULT=$(dpkg -l 2>/dev/null | grep -i "$SEARCH_TERM" | grep "^ii" || true)
print_result $RESULT
fi
# RPM (Red Hat, Fedora, CentOS, openSUSE, etc.)
# ==============================================================================
if command -v rpm &> /dev/null; then
echo "RPM"
RESULT=$(rpm -qa 2>/dev/null | grep -i "$SEARCH_TERM" || true)
print_result $RESULT
fi
# Snap
# ==============================================================================
if command -v snap &> /dev/null; then
echo "Snap"
RESULT=$(snap list 2>/dev/null | grep -i "$SEARCH_TERM" || true)
print_result $RESULT
fi
# AppImage
# ==============================================================================
echo "AppImage"
FOUND_APPIMAGE=false
APPIMAGE_DIRS=("$HOME" "$HOME/Applications" "/opt" "/usr/local/bin")
for dir in "${APPIMAGE_DIRS[@]}"; do
if [ -d "$dir" ]; then
RESULT=$(find "$dir" -maxdepth 5 -name "*.AppImage" 2>/dev/null | grep -i "$SEARCH_TERM" || true)
if [ "$RESULT" ]; then
print_result $RESULT
FOUND_APPIMAGE="true"
fi
fi
done
if [ "$FOUND_APPIMAGE" = false ]; then
echo "$TAB" "No packages found"
fi
Mein Skript ist halb so lang wie das KI-generierte. Die Ausgabe ist angenehmer und – was am wichtigsten ist – es funktioniert. Wobei … ich habe es nur mit nativen Arch-Paketen und Flatpaks ausprobiert, weil ich die anderen Paketformate nicht verwende.
Ausprobieren und Feedback geben
Falls euch die Idee dieses Skriptes gefällt, würde ich mich über eure Testergebnisse und Verbesserungsvorschläge freuen. Dazu speichert ihr das Skript z. B. unter dem Namen "pacform.sh" (Package Format) ab, macht es ausführbar und ruft es z. B. mit "./pacform.sh firefox" auf. Die Ausgabe sieht dann so aus:
./pacform.sh firefox
Arch Packages
firefox 148.0.2-1
firefox-i18n-de 148.0.2-1
firefox-i18n-en-us 148.0.2-1
Flatpak Packages
No packages found
RPM Packages
No packages found
AppImage Files
No packages found
Oder so:
./pacform.sh gimp
Arch
No packages found
Flatpak
GNU Image Manipulation Program org.gimp.GIMP 3.2.2 stable flathub system
RPM
No packages found
AppImage
No packages found
Falls sich jetzt bei den Bash-Profis die Haare sträuben: Ihr habt recht.
Wer einen Alias haben möchte, tippt das in die Shell-Konfigurationsdatei ein (natürlich mit angepasstem Pfad):
alias pac='/home/ralf/dev/pacform/pacform.sh'
Fazit
Vibe-Coding ist ein Zeitfresser, falls man sich selbst ernst nimmt und das Verständnis des Codes und damit die Wartungsfähigkeit in Betracht zieht. Ausserdem führt es zu Depressionen und aus arbeitsrechtlichen Gründen zum Verlust des Jobs, falls man es übertreibt. Doch das ist ein anderes Thema.
Ich wünsche euch sonnige Ostertage.
Titelbild: https://pixabay.com/photos/easter-eggs-multicoloured-3032058/ (modifiziert)
Quelle: https://lumo.proton.me/guest

> Vibe-Coding ist ein Zeitfresser, falls man sich selbst ernst nimmt und das Verständnis des Codes und damit die Wartungsfähigkeit in Betracht zieht
Oder man betrachtet Vibe Coding als ein Werkzeug ähnlich wie 3D-Drucker: Es befähigt mich, für mich Lösungen zu bauen, die zuvor nicht existierten oder teuer eingekauft werden müssten. Von Shell-Skripten über Thunderbird-Extensions hin zu kompletten Python-GTK- und macOS-Swift-Applikationen: Würde es für mich alles ohne Vibe-Coding nicht geben und löst meine Softwarelücken.
So sehe ich das Thema auch. Für mich ist es einfach ein Werkzeug, was mir in der Woche viele Stunden arbeit erspart.
Merci!!
Lustigerweise hatte ich mich heute Morgen genau das gefragt. Scheint zu funktionieren.
Hahaha! Und ich habe heute ein alias gevibe-coded, das mir sagt, ob das Paket in Snap, Flatpak oder Apt installiert ist:
alias woist='_f(){ echo "Suche..."; (apt list --installed "*$1*" 2>/dev/null | grep "/" | sed "s/^/APT: /"); (snap list | grep -i "$1" | awk "{print \"Snap: \" \$1}"); (flatpak list --columns=application | grep -i "$1" | sed "s/^/Flatpak: /"); }; _f'Verfechter der Nutzung von KI (ich bin keiner) würden vielleicht argumentieren, dass du dich immerhin jetzt mit bash-Skripten auseinandergesetzt hast.
So wird ja die Nutzung von KI empfohlen, nämlich deren Funde nur als Basis für eigene Gedanken zu nutzen. In meinem Arbeitsalltag sehe ich aber, dass die Generation KI das nicht tut, sondern einfach die Fehlermeldungen an die KI zurückgibt, solange bis es funktioniert.
Das sind dieselben Leute, die dafür Google, Reddit und etliche andere Plattformen genau für diesen Zweck genutzt haben und dort auch nicht wussten, was passiert. Die Recherchemöglichkeiten von aktuellen KI-Modellen sind allerdings viel besser, als zehn Jahre alte Lösungs-Beispiele von irgendwelchen Websites zu klauben.
Hallo Ralf,
danke für das Script - sehr praktisch. Der AppImage-Abschnitt hat allerdings bei mir kein Ergebnis geliefert, obwohl 2 AppImages vorhanden sind.
Diese Anpassungen waren nötig:
-maxdepthwar in meinem Fall mit 3 zu klein gesetztMit dieser Variante würde es funktionieren:
Und das macht natürlich auch keinen Sinn
$HOMEund$HOME/Applicationsbeide rekursiv nach Dateien zu durchsuchen. Naja, KI halt.Vielen Dank fr. Ich habe den Code im Artikel entsprechend angepasst.
Kann ich bestätigen. Appimage funktioniert jetzt. Danke.
zu DEB
Wenn man „dpkg -l“ ohne weitere Angabe ausführt, dann werden bereits nur installierte Pakete aufgelistet. Einmalig grep anwenden, um das Paket zu finden sollte IMHO reichen. Allerdings zusätzlich noch mit „grep "^ii"“ nur die absichtlich und fertig installierten heraus zu filtern, verwirft die ggf. sinnvolle Information zu Paketen, die in einem schlechten Zustand sind (bspw. „iF“). (Dass man sich in dem genannten Zusammenhang nicht für übriggebliebene Konfigurationen („rc“) interessiert, sähe ich ein und würde dies evtl. ausblenden.)
Es gilt das bereits Gesagte. Das Ganze als Anregung sehen und sich selbst mit beschäftigen. Ein Skript, dass es allen recht macht, gibt es wohl kaum.
Ich habe es unter Debian mit Firefox ausprobiert, funktioniert auch für DEB (zeigt die Debian-Pakete zu Firefox an).
Danke, nett! Für den Debian-Teil habe ich es so geändert:
RESULT=$(dpkg -l "${SEARCH_TERM}*" 2> /dev/null |grep '^ii')Gleich nur potentiell passende Pakete ausgeben (statt der ganzen Liste – so wurde bei mir ursprünglich auch 'plasma-browser-integration' gefunden, da 'Firefox' in der Kurzbeschreibung auftaucht), nur Pakete, die mit dem Suchbegriff anfangen (Geschmackssache), nur erfolgreich installierte (Geschmackssache). Brauche ich das
|| true?Das
|| truewird eigentlich nur benötigt, um in der Funktionprint_result()"No packages found" auszugeben, falls es keinen Treffer gab.|| echo ""würde auch funktionieren, ist aber 3 Zeichen länger ;-)