4

When doing apt install, I would get a list of packages that need to be installed, under the line:

The following NEW packages will be installed:

and if there are none, it would continue without prompt. I tried to retrieve this list, but would fail if there are none because the install would just proceed. I want to get this list without installing it.

I tried something like this:

apt-cache depends --recurse packagename | grep -v " " | sort -u

But it gives a full list including those that are already installed. I want to limit it to those that need to be installed.

I know I can compare the output above with the result of

dpkg --get-selections

to see which are installed and which are not, but it would involve loops within loops and both lists are quite long. There surely must be a more elegant way to do this.

Thanks for any suggestions. (This is my first time to ask a question here)

Edit: I checked out the method using rdepends as given in this question: Recursive dependencies

It would have been what I am looking for, except that it results in a different list from what apt install gives. It even lists dependencies that are uninstallable (which can't be, given that the package itself installs successfully). What I'm looking for is the list of packages that apt would install before the given package. Anyway, I don't understand why the list is different. It should be the same result, right? But since it isn't, then it is not what I am looking for. I would appreciate, however, if someone can explain to me why they give different results.

7

Use: apt -s install ...

Passing the -s option to apt causes it to simulate installation but not actually install or modify anything. That shows what you can expect to see from apt when you install the package, including which packages if any are pulled in to satisfy its (direct and indirect) dependencies.

For example, to find out what will happen when you install the apache2 package, you would run:

apt -s install apache2

That shows you what steps would be taken by sudo apt install apache2.

The -s option can also be spelled as any of --simulate, --just-print, --dry-run, --recon, --no-act. So if you see (or write) any of those, they're doing the same thing.

The -s option is documented in man apt-get and not in man apt (the latter of which doesn't document most features and options), but both apt-get -s install ... and apt -s install ... are supported.

You can likewise simulate other actions with -s, such as the remove action.

Unlike with apt commands that actually make changes to your system, running apt -s as root is optional, so you can omit sudo.

| improve this answer | |
  • Thank you! The -s solved my issue. You are right that it wasn't in the manpage so I didn't discover it. I wonder though, will this approach work across languages? Since I grepped the word "NEW" then it might work only in English. I ask because this will be part of a script. Or is there a way to parse the output of apt without looking for a specific word? – bamm Oct 24 at 6:47
  • 1
    Forget my previous comment. I solved that by calling the command as env LC_MESSAGES=C apt-get -s install packagename – bamm Oct 24 at 9:58
  • After trying many things, including other suggestions here, this seems to be the approach that gives me the most correct answer. Only disadvantage is the need to parse the result. If I can't find a command to give just the list, then this would be the solution. – bamm Oct 24 at 10:19
  • Generally scripts should call apt-get instead of apt, and apt tells you about this whenever its stdout is not connected to a terminal. – Simon Richter Oct 24 at 11:29
  • Thank you Simon. I'll remember that and always use apt-get in scripts from now on. – bamm Oct 24 at 12:05
4

It seems apt -s install (from another answer) does what you need. Other tools you can consider are apt-rdepends and apt-cache. However, they list different packages from apt -s install, so which to use depends on your needs.

  • apt may include packages marked "Suggests" and "Recommends", depending on your configuration.

  • apt-rdepends doesn't exclude packages that are already provided by others. Suppose you have package xyz-ng installed, and it provides xyz. apt-rdepends lists xyz because it is a depends that's not installed, but apt doesn't need to install xyz because it's provided by xyz-ng, which is installed.

    • In the above example, xyz-ng and xyz will conflict. So xyz cannot be installed without removing xyz-ng.
  • apt-cache may include unnecessary packages for other reasons, like other architectures (i386).

Here is example usage of apt-rdepends with output piped to other utilities to clean up the package list:

package="whatever"
apt-rdepends \
        --state-follow=NotInstalled --state-show=NotInstalled \
        -f Depends -s Depends "$package" 2> /dev/null | 
    grep Depends\:\ | 
    sed -E 's@\ \(.*\)$@@ ; s@^\s+Depends\:\ @@' |
    sort -u

Here is an example using aptitude with piped output to clean up the package list:

package="whatever"
aptitude -s -y install "$package" |
    sed -E -e '1h;2,$H;$!d;g' \
           -e 's@(.*\n)+.*NEW\ packages\ will\ be\ installed:\n(.*\n).*RECOMMENDED but will NOT be installed:(\n.*)+@\2@' \
           -e 's@(\{[a-z]\})?\ @\n@g' |
    sort -u
| improve this answer | |
  • Thanks again xiota. I will remember this. It so happened that the apt-get solution worked better for my current (specific) need, but depending on my needs, I can see that your solution will be very useful in the future, especially because the apt-get solution depends on user configuration of Suggests and Recommends, and for situations where I don't need to resolve the Provides. I double checked and noticed that the uninstallable packages given by rdepends are already provided by other packages on my system, hence don't need to be installed anymore. – bamm Oct 24 at 12:47
  • Btw, what does sed -E 's@\ \(.*\)$@@' do? I get the same result with or without that pipe. – bamm Oct 24 at 12:48
  • Some packages show required versions at the end, like (>= 3.14159). That just removes those to get just the pure package name. – xiota Oct 24 at 12:50
0

You can accomplish this with aptitude:

$ aptitude \
  --safe-resolver --no-new-installs install <package>
| improve this answer | |
  • 1
    This didn't work for me though. It just told be <packagename> is not currently installed, so it will not be upgraded. – bamm Oct 24 at 6:49
  • You may add --show-resolver-actions to see what action was taken by the safe-resolver. – bac0n Oct 24 at 7:32
  • I did sudo aptitude safe-upgrade --show-resolver-actions --no-new-installs <packagename> but it still says <packagename> is not currently installed, so it will not be upgraded. Anyway, I'm not upgrading a package; I want to check the list of packages that will be installed together with a package. – bamm Oct 24 at 10:03
  • This should produce the same result. – bac0n Oct 24 at 11:49
  • I noticed your edit and so I tried changing aptitude safe-upgrade to aptitude install. This time the message said: Resolving dependencies... No packages will be installed, upgraded, or removed. – bamm Oct 24 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.