I've got a command that provide me the list of direct dependencies of some package. Here it is, for example:
# get-dep some-random-package
libunistring-1.0
libidn2-2.3.2
glibc-2.35-163
xz-5.2.7
gcc-11.3.0-lib
attr-2.5.1
acl-2.3.1
gmp-with-cxx-stage4-6.2.1
coreutils-9.1
findutils-4.9.0
bash-5.1-p16
pcre-8.45
gnugrep-3.7
zstd-1.5.2
zstd-1.5.2-bin
zlib-1.2.13
openssl-3.0.7
libxml2-2.10.3
bzip2-1.0.8
libarchive-3.6.1-lib
libarchive-3.6.1
gzip-1.12
some-random-package
I need to get the whole list of dependencies.
by using this get-dep
command I am trying to write bash function that give me the whole list of dependencies recursivly.
At first glance this function should recursivly pass through each package.
I tried to do next:
#!/bin/bash -e
get_the_whole_list_of_dependencies() {
local list=$(get-dep "${1}")
local cnt=$(echo "${list}"| wc -l)
if [ "${cnt}" == 1 ]; then
echo "${list}"
else
for f in ${list}; do
get_the_whole_list_of_dependencies "${f}"
done
fi
}
get_the_whole_list_of_dependencies some-random-package
However something goes wrong and the function is turned to be an endless loop.
Does anybody help me with that issue?
As discussed in comments your algorithm is inefficient because it processes the same package as many times as it is encountered. Another bash array could be used to keep track of the already seen packages and avoid this.
Note also that your script prints only the leaves of your dependency tree while you state that you want the whole list of dependencies recursively.
If you use a bash array to avoid processing twice the same package, and if your bash supports them, better use an associative array (local -A seen
) as it makes very easy to check if a package has already been seen.
Example:
_get_the_whole_list_of_dependencies() {
printf '%s\n' "$1"
local -a list=($(get-dep "$1"))
seen["$1"]=1
local -i cnt=${#list[@]}
if (( cnt > 1 )); then
for f in "${list[@]}"; do
if ! [[ -v seen["$f"] ]]; then
_get_the_whole_list_of_dependencies "$f"
fi
done
fi
}
get_the_whole_list_of_dependencies() {
local -A seen=()
_get_the_whole_list_of_dependencies "$1"
}
And then:
$ get_the_whole_list_of_dependencies zlib
zlib
xz
gettext
gettext-runtime
libiconv
gperf
gettext-tools-libs
libtextstyle
ncurses