Format eines installierten Pakets ermitteln

  Ralf Hersel   Lesezeit: 7 Minuten  🗪 14 Kommentare Auf Mastodon ansehen

Warum sich Vibe-Coding nicht lohnt und wie man mit einem Befehl herausfindet, in welchem Format eine Anwendung installiert ist.

format eines installierten pakets ermitteln

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

Tags

Pakete, Paketformat, Vibe Code, Bash-Shell, Skript

Oliver
Geschrieben von Oliver am 2. April 2026 um 09:30

> 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.

Lucas Peters Admin
Geschrieben von Lucas Peters am 3. April 2026 um 18:46

So sehe ich das Thema auch. Für mich ist es einfach ein Werkzeug, was mir in der Woche viele Stunden arbeit erspart.

Taddaeus
Geschrieben von Taddaeus am 2. April 2026 um 10:57

Merci!!

Lustigerweise hatte ich mich heute Morgen genau das gefragt. Scheint zu funktionieren.

Walter Paaser
Geschrieben von Walter Paaser am 4. April 2026 um 16:05

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'

Naja
Geschrieben von Naja am 2. April 2026 um 11:23

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.

Oliver
Geschrieben von Oliver am 2. April 2026 um 16:33

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.

fr
Geschrieben von fr am 2. April 2026 um 11:54

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:

  • die Variable FOUND_APPIMAGE ist bei einem Treffer nicht mehr "false"
  • die Verzeichnis-Tiefe -maxdepth war in meinem Fall mit 3 zu klein gesetzt

Mit dieser Variante würde es funktionieren:

# 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
Robert
Geschrieben von Robert am 2. April 2026 um 17:45

Und das macht natürlich auch keinen Sinn $HOME und $HOME/Applications beide rekursiv nach Dateien zu durchsuchen. Naja, KI halt.

Ralf Hersel Admin
Geschrieben von Ralf Hersel am 4. April 2026 um 22:39

Vielen Dank fr. Ich habe den Code im Artikel entsprechend angepasst.

Jens
Geschrieben von Jens am 2. April 2026 um 17:04

Kann ich bestätigen. Appimage funktioniert jetzt. Danke.

Col.Row
Geschrieben von Col.Row am 3. April 2026 um 13:05

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.

MichaelM
Geschrieben von MichaelM am 3. April 2026 um 16:26

Ich habe es unter Debian mit Firefox ausprobiert, funktioniert auch für DEB (zeigt die Debian-Pakete zu Firefox an).

kamome
Geschrieben von kamome am 15. April 2026 um 18:53

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?

fr
Geschrieben von fr am 17. April 2026 um 10:40

Das || true wird eigentlich nur benötigt, um in der Funktion print_result() "No packages found" auszugeben, falls es keinen Treffer gab. || echo "" würde auch funktionieren, ist aber 3 Zeichen länger ;-)