How to download all dependencies and packages to directory
Asked Answered
T

14

118

I'm trying to install a package on a machine with no Internet connection. What I want to do is download all the packages and dependences on a machine WITH an Internet connection and then sneaker-net everything to the offline computer.

I've been playing with the apt-get and apt-cache but I haven't figured out a quick and easy way to download the package and dependencies in one swoop to a directory of my choosing. How would I do this? Am I going about this problem correctly? How would you install offline packages that have a lot of dependencies?

Twaddle answered 7/12, 2012 at 4:10 Comment(1)
C
44
# aptitude clean
# aptitude --download-only install <your_package_here>
# cp /var/cache/apt/archives/*.deb <your_directory_here>
Ceruse answered 7/12, 2012 at 5:40 Comment(9)
This only works if you do not have the package or its dependencies installed locally.Jewelfish
In real world situations this doesn't work for you. In most cases many of the dependency packages have been installed, so --download-only won't download them and won't put them in /var/cache/apt/archive/ directory. so you end up with incomplete dependency packages.Uraemia
I guess this will work if you can keep both installations, source (presumably connected to the Internet) and the target (with no Internet connection) exactly the same, for example installing Ubuntu from same ISO on both machines and then cleaning all .debs on source, then installing desired stuff, copying all newly downloaded .debs to target machine and then running sudo dpkg -i *.deb???Egotism
using reinstall command instead of install will download package even if they are already installedNeoplasm
Doesn't get dependencies at all for me (Ubuntu 18.04)Jorgan
works also for apt-get just with rm -r /var/cache/apt/archives/* instead of first commandYoon
This is what finally worked for me. I started an ubuntu 20.04 container which is clean and bind mount some host directory to copy the stuff out. For example 1 apt-get update 2 apt-get install software-properties-common 3 add-apt-repository ppa:ondrej/php 4 apt-get install aptitude 5 aptitude search php 6 aptitude search php7.2-memcached 7 aptitude clean 8 aptitude --download-only install php7.2-memcachedSnapback
Then for loading these things, there is a seemingly simple guide to creating a local file repo for apt, but it ends up being way to complicated (you hit missing Release file). Instead just run dpkg -i on that directory and keep running until it stops complaining. Poor man's dependency loader. Just repeatedly run this for example: for i in ls php7.2-*; do dpkg -i $i; doneSnapback
Does not download dependenciesRedman
N
125

The marked answer has the problem that the available packages on the machine that is doing the downloads might be different from the target machine, and thus the package set might be incomplete.

To avoid this and get all dependencies, use the following:

apt-get download $(apt-rdepends <package>|grep -v "^ ")

Some packages returned from apt-rdepends don't exist with the exact name for apt-get download to download (for example, libc-dev). In those cases, filter out those exact names (be sure to use ^<NAME>$ so that other related names, for example libc-dev-bin, that do exist are not skipped).

apt-get download $(apt-rdepends <package>|grep -v "^ " |grep -v "^libc-dev$")

Once downloaded, you can move the .deb files to a machine without Internet and install them:

sudo dpkg -i *.deb
Nichol answered 14/12, 2014 at 12:53 Comment(10)
I used apt-rdepends because it would recursively list the needed packages. However, both solutions have the still (minor IMO) problem that some dependencies can only be provided by packages that are actually named like the dependency. Some dependencies are resolved by packages named differently, but having a corresponding 'Provides' tag. For example, I ran into the problem of having a reference on debconf-2.0 unresolved - my kludgy but very workable solution is to manually filter those (usually very few) packages out with another grep -v added to the pipe.Nichol
Are you certain rdepends means recursive dependencies? I think it's reverse dependencies.Halbeib
For my above comment above I was confusing "apt-cache rdepends" with apt-rdepends. My mistake - you were correct and this is powerful.Halbeib
No worries. I now edited it back to say apt-rdepends again.Nichol
This doesn't work for me because apt-rdepends spits out libc-dev as one of the packages I need. Except that doesn't exist in the Ubuntu repository (I searched with apt-cache and tried updating everything too). So the command fails and nothing is downloaded: E: Can't select candidate version from package libc-dev as it has no candidateTichonn
Worked around the error by chaining two grep together. apt-get download $(apt-rdepends <package>|grep -v "^ "|grep -v "libc-dev")Tichonn
Yeah, it is all still somewhat imperfect. I tried to say that with '[..] manually filter those (usually very few) packages out with another grep -v added to the pipe.'Nichol
After downloading all the the .deb files, how does one then install them onto an Ubuntu machine that is disconnected from the Internet? Do they need to be installed in reverse-dependancy order? Is there a way to point apt-get install on the disconnected machine to the copied .deb files so it can install from the offline folder?Etra
A more general way to prevent the command crashing from a problematic package like libc-dev is to use a for-loop: for PKG in $(apt-rdepends <package> | grep -v "^ "); do apt download $PKG; donePalpitation
apt-rdepends doesn't seem to understand A | B dependencies. So this will produce a list of dependencies that is in excess of requirement. Eg: libpython3.10-stdlib depends on media-types | mime-support. Installing mime-support pulls in perl and a bunch of other things you don't actually need.Kamala
E
79

Same question already answered here: How to list/download the recursive dependencies of a debian package?

try:

PACKAGES="wget unzip"
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests \
  --no-conflicts --no-breaks --no-replaces --no-enhances \
  --no-pre-depends ${PACKAGES} | grep "^\w")
Emphysema answered 3/8, 2017 at 16:21 Comment(8)
This script works great.. downloaded the entire dependency tree. I'm wondering if we could also auto-generate a file having the dpkg commands in proper order, so that the packages with no other dependencies load up first? At present it's just a brute-force sudo dpkg -i *.deb several times.Angelineangelique
@NikhilVJ Once you've downloaded your dependencies you can use apt-get install --no-download <PACKAGE> and it will search only the local cache. It should be able to sort out the dependency order as it normally does though.Morphology
Changed your apt-get download line to start like this so that the files are downloaded to the current directory. apt-get download -o Dir::Cache="./" -o Dir::Cache::archives="./"Essa
Why use --no-pre-depends? I think pre-depends is required to be installed.Cleghorn
I found that it downloaded both the amd64 and i386 versions for some packages. To download only the version i needed, I extended the grep with in the following way: grep "^\w" | grep -v "i386" (To ignore the i386 ones)Nonreturnable
@Own: The -o Dir::Cache and -o Dir::Cache::archives configuration options are for "apt-get --download-only install" and not for "apt-get download".Sicken
@GalAvineri you could use the output of $(dpkg --print-architecture) to only include packages matching your current system architecture.Seeing
This is complicated with "or" packages (with |Depends) and "or" packages in metadata, (with the package on row below), taking unnecessary packages. If the right Package files are on the computer, the easy solution to test the required files is apt install --dry-run packageGavotte
C
44
# aptitude clean
# aptitude --download-only install <your_package_here>
# cp /var/cache/apt/archives/*.deb <your_directory_here>
Ceruse answered 7/12, 2012 at 5:40 Comment(9)
This only works if you do not have the package or its dependencies installed locally.Jewelfish
In real world situations this doesn't work for you. In most cases many of the dependency packages have been installed, so --download-only won't download them and won't put them in /var/cache/apt/archive/ directory. so you end up with incomplete dependency packages.Uraemia
I guess this will work if you can keep both installations, source (presumably connected to the Internet) and the target (with no Internet connection) exactly the same, for example installing Ubuntu from same ISO on both machines and then cleaning all .debs on source, then installing desired stuff, copying all newly downloaded .debs to target machine and then running sudo dpkg -i *.deb???Egotism
using reinstall command instead of install will download package even if they are already installedNeoplasm
Doesn't get dependencies at all for me (Ubuntu 18.04)Jorgan
works also for apt-get just with rm -r /var/cache/apt/archives/* instead of first commandYoon
This is what finally worked for me. I started an ubuntu 20.04 container which is clean and bind mount some host directory to copy the stuff out. For example 1 apt-get update 2 apt-get install software-properties-common 3 add-apt-repository ppa:ondrej/php 4 apt-get install aptitude 5 aptitude search php 6 aptitude search php7.2-memcached 7 aptitude clean 8 aptitude --download-only install php7.2-memcachedSnapback
Then for loading these things, there is a seemingly simple guide to creating a local file repo for apt, but it ends up being way to complicated (you hit missing Release file). Instead just run dpkg -i on that directory and keep running until it stops complaining. Poor man's dependency loader. Just repeatedly run this for example: for i in ls php7.2-*; do dpkg -i $i; doneSnapback
Does not download dependenciesRedman
U
23

The aptitude --download-only ... approach only works if you have a debian distro with internet connection in your hands.

If you don't, I think it is better to run the following script on the disconnected debian machine:

apt-get --print-uris --yes install <my_package_name> | grep ^\' | cut -d\' -f2 >downloads.list

move the downloads.list file into a connected linux (or non linux) machine, and run:

wget --input-file myurilist

this downloads all your files into the current directory.After that you can copy them on an USB key and install in your disconnected debian machine.

Credits: http://www.tuxradar.com/answers/517

Untried answered 7/10, 2014 at 14:59 Comment(4)
apt-get approach is only working when package is not installedAuspice
Adding -qq to the apt-get line removes the need for the grep (and the need for --assume-yes)Mitran
since (I think) apt version 0.8.11 (ubuntu 11.04) one can use the "download" option for this, so you CAN use it, even if the package is installed already. So use apt-get --print-uris --yes download <my_package_name> |... instead of "install", or alternatively use the option "--reinstall" with install, like @ozma says (@A.Binzxxxxxx)Pitchfork
that just saved my crashed linux installation, thanks a lot!!Incapacious
H
10

This will download all the .debs to the current directory, and will not fail if it can't find a candidate. This script does not require sudo to run.

nano getdebs.sh && chmod +x getdebs.sh && ./getdebs.sh

#!/bin/bash

package=ssmtp

apt-cache depends "$package" | grep Depends: >> deb.list

sed -i -e 's/[<>|:]//g' deb.list

sed -i -e 's/Depends//g' deb.list

sed -i -e 's/ //g' deb.list

filename="deb.list"

while read -r line
do
    name="$line"
    apt-get download "$name"
done < "$filename"

apt-get download "$package"

I used this as my example because I was actually trying to download the dependencies for ssmtp and it failed on debconf-2.0, but this script did what I needed.

Hashish answered 11/10, 2016 at 0:2 Comment(3)
this worked great for me. I had to add another line to handle PreDepends though. thanks for sharing!Midday
How do I use this to download packages for some other version of ubuntu like version 14Epidemic
@Epidemic if you find out let me know, but the obvious solution is to fire up Ubuntu 14 and run script :PHashish
H
9

Somewhat simplified (and what worked for me) way that worked for me (based on all the above)
Note that dependencies hierarchy can go deeper then one level

Get dependencies of your package

$ apt-cache depends mongodb | grep Depends:
  Depends: mongodb-dev
  Depends: mongodb-server

Get urls:

sudo apt-get --print-uris --yes -d --reinstall install mongodb-org mongodb-org-server mongodb-org-shell mongodb-org-tools | grep "http://" |  awk '{print$1}' | xargs -I'{}' echo {} | tee files.list
wget --input-file files.list
Homolographic answered 27/7, 2015 at 6:8 Comment(3)
Thanks a lot for this. I actually wonder if there is a way to tell APT to also download dependencies and cache them in /var/cache/apt/archives. I wanted to download texlive-full --install-recommends and only ended up with a metapackage called texlive-full in my archives.Brouwer
I don't know about cache. You will have to try it yourself askubuntu.com/questions/463380/…Homolographic
its a bit old but I just found out that if the files are in apt cache it won't be downloaded again. "apt-get clean" solved it.Homolographic
F
6

I used apt-cache depends package to get all required packages in any case if the are already installed on system or not. So it will work always correct.
Because the command apt-cache works different, depending on language, you have to try this command on your system and adapt the command. apt-cache depends yourpackage
On an englisch system you get:

$ apt-cache depends yourpackage
node
  Depends: libax25
  Depends: libc6


On an german system you get: node

  Hängt ab von: libax25
  Hängt ab von: libc6


The englisch version with the term:
"Depends:"
You have to change the term "yourpackage" to your wish twice in this command, take care of this!

$ sudo apt-get --print-uris --yes -d --reinstall install yourpackage $(apt-cache depends yourpackage | grep "  Depends:" |  sed 's/  Depends://' | sed ':a;N;$!ba;s/\n//g') | grep ^\' | cut -d\' -f2 >downloads.list


And the german version with the term:
"Hängt ab von:"
You have to change the term "yourpackage" to your wish twice in this command, take care of this!
This text is used twice in this command, if you want to adapt it to your language take care of this!

$ sudo apt-get --print-uris --yes -d --reinstall install yourpackage $(apt-cache depends yourpackage | grep "Hängt ab von:" |  sed 's/  Hängt ab von://' | sed ':a;N;$!ba;s/\n//g') | grep ^\' | cut -d\' -f2 >downloads.list


You get the list of links in downloads.list
Check the list, go to your folder and run the list:

$ cd yourpathToYourFolder

$ wget --input-file downloads.list


All your required packages are in:

$ ls yourpathToYourFolder
Franconia answered 6/6, 2015 at 16:41 Comment(4)
Once the files have been obtained, what command would you use to make sure all these files are used when performing an offline installation?Prediction
I think if you do dpkg -i package .deb package2.deb, dpkg will figure out the order of installationHashish
This didn't work for me because one of my Depends was <debconf> which wasn't handled correctly in the One liner, but I'm sure it will work for lots of things, the general concept works, but I used ozma's answerHashish
I wonder, if you ran apt-get with env var LANG=en, you wouldn't need to grep for that german word, right? and your solution would apply to everyoneJelsma
S
4

This will download all packages and dependencies (no already installed) to a directory of your choice:

sudo apt-get install -d -o Dir::Cache=/path-to/directory/apt/cache -o Dir::State::Lists=/path-to/directory/apt/lists packages

Make sure /path-to/directory/apt/cache and /path-to/directory/apt/lists exist. If you don't set -o Dir::Cache it points to /var/cache/apt, Dir::State::Lists points to /var/lib/apt/lists (which keeps the index files of available packages)

Both -o options can be used with update and upgrade instead of install.

On different machine run the same command without '-d'

Sontag answered 13/2, 2019 at 16:3 Comment(3)
upvoting this answer as this allows for proper behavior of dist-upgrade/full-upgrade to remove packages if necessary, but install new ones from the cacheLuvenialuwana
This is the best option if you can get a copy of /var/list/apt/lists from the offline machine to the online machine. Saves you from downloading and copying a bunch of packages that are already installed.Fancie
used with --reinstall flag to get all packages. some of my dependencies were in a custom keyring (because of ros 2). will write if i solve it. Otherwise this is better than dpkg -i if dependencies are problemRubicon
S
2

I'm assuming you've got a nice fat USB HD and a good connection to the net. You can use apt-mirror to essentially create your own debian mirror.

http://apt-mirror.sourceforge.net/

Separatist answered 7/12, 2012 at 4:23 Comment(1)
No I don't. Ill play with apt-mirror but I don't have a fat USB HD or a good connection to the net. I really just want to download the packages I absolutely need.Twaddle
H
1

On modern Ubuntu systems (for example, 22.04):

apt clean
apt update
apt install --download-only  freeipa-client

After you can find deb-files in

ls -l /var/cache/apt/archives/
Halfwitted answered 5/7, 2022 at 8:29 Comment(0)
M
0

IF you accept the caveat that there may be dependencies already installed on your system, then the easiest way is to go apt-get install --simulate <your_package>, this will first list all the deps it will install, then copy the list of packages, then apt-get download <the_list_of_packages>


e.g. for qt5-gtk2-platformtheme on a xubuntu-21.04 MINIMAL INSTALL you'll get (after apt-get install --simulate) the following:

libdouble-conversion3 libmd4c0 libpcre2-16-0 libqt5core5a libqt5dbus5 libqt5gui5 libqt5network5 libqt5svg5 libqt5widgets5 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0 libxcb-xinput0 libxcb-xkb1 libxkbcommon-x11-0 qt5-gtk-platformtheme qttranslations5-l10n

then you just cd in a folder of your choice, do apt-get download <the_list_above>, and you have them all d/w in there. you can then dpkg -i *.deb

Milamilady answered 30/8, 2021 at 19:16 Comment(0)
B
0

Complementing and automating the exclusion of ALL conflictive dependencies (dependencies not found) by the command given by @onno:

apt-get download $(apt-rdepends <package>|grep -v "^ " |grep -v "^conflictiv-dependency$")

At least for Ubuntu, where the Error Message format is as follows:

E: Can't select candidate version from package <package> as it has no candidate

The following script Downloads all Found Dependencies, Excluding not Found ones:

#!/bin/bash
rm -f error.txt
apt download $(apt-rdepends $1 | grep -v "^ ") 2> error.txt
#IF THERE WAS ERRORS (DEPENDENCIES NOT FOUND)
if [ $(cat error.txt | wc -l) -gt 0 ]
then
    partial_command="\("
    while read -r line
    do
        conflictive_package="$(awk '{split($0,array," "); print array[8]}' <<< $line)"
        partial_command="$partial_command$conflictive_package\|"
    done < error.txt
    
    partial_command="$(awk '{print substr($0, 1, length($0)-2)}' <<< $partial_command)\)"
    eval "apt download \$(apt-rdepends $1 | grep -v '^ ' | grep -v '^$partial_command$')"
fi
rm error.txt
Briannabrianne answered 20/2, 2022 at 2:20 Comment(0)
S
0

It works with me

sudo apt-get reinstall --download-only <your software>

for example

sudo apt-get reinstall --download-only ubuntu-restricted-extras

For accessing installed .deb files, you can look in this path:

/var/cache/apt/archives
Spicebush answered 2/12, 2022 at 12:25 Comment(0)
T
0

Adding a more modern answer to this question: The problem with other answers is that the machine that downloads the dependencies needs to be in a sense "clean" to get all dependencies. Enter docker!

  • Connect the removeable storage device and note its mounted path /mnt/store
  • Begin an interactive docker container with your target OS (e.g. ubuntu:22.04) and the store mounted:
docker run --rm -it -v /mnt/store:/store ubuntu:22.04
apt-get update
apt-get --download-only install <your_package_here>
cp /var/cache/apt/archives/*.deb /store

And all the required .debs will be on the removable storage. FInally connect the removable storage to the offline machine, note the mounted path /mnt/path and run (as root):

dpkg -i /mnt/store/*.deb

Rinse and repeat with any other packages you fancy.

Tavie answered 28/3 at 19:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.