61

I need to list/download all the recursive dependencies of a debian package.

Suppose i need to install package a.deb and it depends on package b.deb and again package b.deb depends on package c.deb.

I need to download all the recursive dependent packages so that they can be installed on some other machine without any internet access.

Thanks.

Oerd
  • 2,256
  • 1
  • 21
  • 35
Bharat Bhansali
  • 627
  • 1
  • 6
  • 4

4 Answers4

106

For some reason apt-rdepends did not work for me (when searching the 'docker-engine' package, it missed the dependency onto libltdl7 which was introduced with docker-engine 1.11.1-0). UPD Supposedly owing to the fact that apt-rdepends doesn't follow and doesn't list Recommends by default. And doesn't follow virtual packages.

So I came up with following command suite.

Recursively list dependencies

$ apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances <your-package-here> | grep "^\w" | sort -u

(you obviously have to change <your-package-here> at the end of the line with the package you want to analyze)

The key here is the --recurse option. Unfortunately, you cannot specify the content you want (or I did not find the way) so you need to turn off all unwanted dependencies to keep only "dependencies". It is a bit verbose and hard to remember!

From the apt-cache man page:

Per default the depends and rdepends print all dependencies

Download those dependencies

So in order to download those dependencies, run following command which will download them into the current working directory:

$ apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances <your-package-here> | grep "^\w" | sort -u)

Optionally, to install those dependencies

This extends slightly the asked question, but it seems to match the intent of the question.

You need to build the index of the just downloaded packages. This is done from the same folder where all .deb where downloaded:

$ dpkg-scanpackages . | gzip -9c > Packages.gz

Then just copy that folder (all .deb + the Packages.gz file) to the target system which does not have Internet access and add the folder to the APT source list.

$ echo "deb file:<your folder here> ./" | sudo tee -a /etc/apt/sources.list
$ sudo apt-get update

Et voilà

On a system w/o Internet access, I can install a package (Docker in my example) and its dependencies:

$ sudo apt-get install docker-engine
x-yuri
  • 16,722
  • 15
  • 114
  • 161
Yann Vo
  • 1,793
  • 1
  • 15
  • 10
  • Once you know the dependencies you need, you can edit /etc/apt/sources.list and add /etc/apt/preferences.d/somename.pref, if the machine that is offline has a newer (it won't work for older, I tried) version of Ubuntu. See: medium.com/@george.shuklin/… – Peeter Kokk Sep 07 '17 at 07:19
  • 2
    This is great! Thanks a bunch! I'd like to add that I had to make the following changes for the installation to work on my Ubuntu 18.04 fresh install: echo "deb [allow-insecure=yes] file: ./" | sudo tee -a /etc/apt/sources.list and sudo apt-get install --allow-unauthenticated docker-engine – Areeb May 10 '18 at 06:31
  • You can also use "deb [trusted=yes] file:/your/folder/path/here/ ./" With that I haven't had the need to use "--allow-unauthenticated" in my apt commands. – copeland3300 Apr 18 '19 at 21:16
  • Also, user might want to omit `--no-recommends`, since they're installed by default. – x-yuri Jul 04 '19 at 17:13
  • 1
    I get the error when I try to do apt-get update "E: The repository 'file:/home/myusernamehere/Pulled_Installers ./ Release' does not have a Release file. N: Updating from such a repository can't be done securely and therefore is disabled by default. When I tried to add [allow-insecure=yes] after the deb, then when I try to update I get E: Conflicting values set for option ALLOW_INSECURE regarding source E: The list of sources could not be read. @YannVo – Jibril Aug 16 '21 at 21:09
  • I actually got the apt-update to work, but when I try to install any given package (in this case, libfftw3-dev), it fails unable to target its dependencies. Those dependencies are in the target folder that I made the Packages.gz from. I did get an error at one point about not having a Release. @YannVo – Jibril Aug 16 '21 at 21:29
  • @Jibril I can reproduce your issue but I am not sure how to resolve it, sorry! If you find the answser, don't hesitate to share it! – Yann Vo Aug 30 '21 at 16:18
  • @Jibril The solution to `E: The repository ... does not have a Release file` was trusting the sources.list entry `echo "deb [trusted=yes] file: ./ | sudo tee -a /etc/apt/sources.list`. Found [here](https://askubuntu.com/questions/170348/how-to-create-a-local-apt-repository#comment1865312_176546) – Zegarek Oct 13 '22 at 16:37
9

You can use apt-rdepends for getting all the dependencies for a package recursively. And by piping the result to grep you can have only the package names and omit unneeded information.

Example:

 $ apt-rdepends cowsay | grep -E '^[a-zA-Z0-9]'

Output:

cowsay
perl
libbz2-1.0
libc6
libgcc1
gcc-4.9-base
multiarch-support
libdb5.3
libgdbm3
dpkg
liblzma5
libselinux1
libpcre3
tar
libacl1
libattr1
zlib1g
install-info
perl-base
perl-modules

You can then download those packages using apt-get download $package and install them offline on your machine.

By default, apt installs Recommends, so you might want to run apt-rdepends like so:

apt-rdepends -f Depends,PreDepends,Recommends -s Depends,PreDepends,Recommends cowsay

Since apt-rdepends by default follows and shows only Depends, PreDepends.

x-yuri
  • 16,722
  • 15
  • 114
  • 161
Mehdi Yedes
  • 2,267
  • 2
  • 14
  • 14
2

As midihenry pointed out - install the apt-rdepends package and then run this

$ apt-rdepends gcc | awk '$1 ~ /^Depends:/{print $2}' | xargs apt-get download

this line will get all dependencies recursively and, looking at the second pipe, will download all the packages by name from the stdio, which is what the line -

awk $1 ~ /^Depends:/{print $2} does. prints out the names of packages. If you run these commands additively, you'll see what i mean.

Community
  • 1
  • 1
Evgeny Danilenko
  • 181
  • 2
  • 10
1

Here is a bash command to download a debian package along with its recursive dependencies. Unlike the other answers, this command wont fail if one of the packages returned by apt-rdepends cannot be downloaded.

for PKG in $(apt-rdepends <package> | grep -v "^ ");  do apt download $PKG; done
tpl
  • 197
  • 1
  • 7
  • The loop is kind of unnecessary; `apt download $(apt-rdepends "$1" | grep -v '^ ')` but the requirement to install a separate utility `apt-rdepends` just for this is also kind of unattractive. (Separately, [probably don't use upper case for your private variables.](https://stackoverflow.com/questions/673055/correct-bash-and-shell-script-variable-capitalization)) – tripleee Mar 23 '23 at 06:10