Skip to content

Instantly share code, notes, and snippets.

@parsapoorsh
Created December 30, 2025 16:20
Show Gist options
  • Select an option

  • Save parsapoorsh/544113c641846389a7099b90cfaef901 to your computer and use it in GitHub Desktop.

Select an option

Save parsapoorsh/544113c641846389a7099b90cfaef901 to your computer and use it in GitHub Desktop.
search a dir and list all debian packages that own those path
#!/usr/bin/env bash
# exit on unbound variable
set -u
# enable colors if appropriate
if [[ -t 1 && -z "${NO_COLOR-}" && "${TERM-}" != "dumb" ]]; then
# ANSI colors
NC='\033[0m' # no color
RED='\033[1;31m'
GREEN='\033[0;32m'
else
NC=""
RED=""
GREEN=""
fi
echo_stderr() {
echo "$@" >&2
}
echo_error() {
printf "${RED}Error${NC}: %b\n" "$@" >&2
}
usage_exit() {
filename=$(basename $0)
echo_stderr "Usage: $filename <DIRECTORY> [MAX_DEPTH=1]"
echo_stderr "Example: $filename /etc/apt/"
exit 1
}
# check if DIRECTORY was provided
if [ $# -lt 1 ]; then
usage_exit
elif [ $# -gt 2 ]; then
echo_error "Unknown argument: ${@:3}"
usage_exit
fi
SEARCH_DIR=$(realpath --no-symlinks "$1")
# check if directory exists
if [ ! -d "$SEARCH_DIR" ]; then
echo_error "'$SEARCH_DIR': not a directory"
usage_exit
fi
# check if MAX_DEPTH was provided
MAX_DEPTH=1
if [ $# -ge 2 ]; then
# check if MAX_DEPTH is an integer >= 1
if ! [[ "$2" =~ ^[0-9]+$ ]] || [ "$2" -lt 0 ]; then
echo_error "MAX_DEPTH must be an integer >= 0"
usage_exit
else
MAX_DEPTH="$2"
fi
fi
# get all paths as arg1 arg2 argN
# then give it to dpkg-query
mapfile -t list_paths < <(find "$SEARCH_DIR" -maxdepth "$MAX_DEPTH" -print 2>/dev/null)
# in my tests, dpkg returnes in the same order as input args
mapfile -t list_dpkg_output < <(dpkg-query --search "${list_paths[@]}" 2>&1)
for idx in "${!list_paths[@]}"; do
path=${list_paths[idx]}
line=${list_dpkg_output[idx]}
# make sure both list items are matched
if [[ "$line" != *"$path"* ]]; then
echo_error "BUG: path is not in line"
echo_stderr "path=$path"
echo_stderr "line=$line"
exit 1
fi
# for cleaner output
relative_path=$(realpath -e --no-symlinks "$path")
pkg_names=$(echo "$line" | awk -F ": " '{print $1}')
pkg_color="$GREEN"
# means error
if [[ "$pkg_names" == "dpkg-query" ]]; then
error_msg=$(echo $line | awk -F ": " '{print $2}' | awk -F "$path" '{print $1}')
pkg_names="NONE"
pkg_color="$RED"
fi
printf "${pkg_color}%s${NC} | %s\n" "$pkg_names" "$relative_path"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment