8

How can I run a command before apt-get starts to download a package?

I know about the dpkg pre-invoke hook ( hook a script to apt-get ), but that seems to be run after the download.

$ apt-get update
Get: 11 http://security.debian.org/ wheezy/updates/main qemu amd64 1.1.2+dfsg-6a+deb7u7 [115 kB]
Fetched 70.9 MB in 10s (6,776 kB/s)
refreshing freenet index
--2015-05-19 15:55:25--  http://127.0.0.1:8888/freenet:USK@oRy7ltZLJM-w-kcOBdiZS1pAA8P-BxZ3BPiiqkmfk0E,6a1KFG6S-Bwp6E-MplW52iH~Y3La6GigQVQDeMjI6rg,AQACAAE/deb.mempo.org/-42/

What we need is to run a command before the download. More exactly: The script must run after calling apt-get but before apt-get accesses any online resource.

Is there something like a Pre-Download hook?

It is important that the installation can be done without having to replace the script apt-get (and without doing anything else which could be undone by an update).

6
  • 2
    You could declare a function named apt-get which would itself call the real apt-get. Depending on the scope you want it to have, the function could be declared either in /etc/profile or ~/.profile or ~/.bashrc.
    – user43791
    Commented May 19, 2015 at 20:23
  • What exactly does "The script must run after calling apt-get but before apt-get accesses any online resource" mean? What part of the producion apt-get needs to be running before your hook can execute properly?
    – jthill
    Commented May 20, 2015 at 1:27
  • @jthill we need to trigger a download of a given URL before any other URL gets accessed. The reason is that we download from freenet (decentralized anonymous datastore used as deb repository) and we want to trigger one aggressive search for the most recent version before downloading anything. Commented May 23, 2015 at 18:54
  • From comments, you're asking how to replace a system command in a way that can't be bypassed and can't be removed even by the system's installer. You're asking how to rootkit the system.
    – jthill
    Commented May 23, 2015 at 20:29
  • It would be helpful if you could describe your use case. Or in other words, what are you trying to do? Commented May 27, 2015 at 11:02

5 Answers 5

10

What about using apt pre/post-invoke hooks?

Essentially it is similar to dpkg pre/post-invoke hooks but for apt (which I'm assuming is actually the important one in your usage scenario). AFAIK there are others but I've only used like this.

E.g.

$ sudo cat /etc/apt/apt.conf.d/05new-hook
APT::Update::Pre-Invoke {"your-command-here"};
7
  • 2
    Apt doesn't provide a pre-invoke hook for Upgrade or Install though, so this only works for apt-get update. Commented May 16, 2017 at 14:09
  • True, but I was answering the question specifically! :) You can use dpkg hooks (as per the OP) for anything which requires pre/post install tweaks. Commented May 17, 2017 at 3:31
  • Kind of; assuming that update is always run before upgrade/install. Hooking all commands before network access occurs appears to be impossible with the currently (2017-05-17) available apt hooks. This is still the best answer for scripting but it doesn't help for things like existing automatic update scripts. Commented May 17, 2017 at 13:37
  • Oh ok, I get you now. Sorry; yes you have a really good point. So you can tweak apt-get update, but apt-get install will still download, before the dpkg hooks will run?! Hmmm, that really sucks! Commented May 19, 2017 at 8:03
  • What you are trying to do? If you want auto updates but only install from specific repos (e.g. Debian security), then you can use cronapt with a script like TurnKey's cronapt script[1]. Split your sources.list entries into separate files; the ones that you want auto updates from go in security.sources.list. [1] github.com/turnkeylinux/common/blob/master/conf/turnkey.d/… Commented May 19, 2017 at 8:36
3

First determine where is apt-get using whereis apt-get or which apt-get; I will assume it's in /usr/bin/apt-get

Then create a file in /usr/local/bin/apt-get with this content:

#!/bin/bash
# (commands to run before apt-get)
exec /usr/bin/apt-get "$@"

now chmod +x /usr/local/bin/apt-get.

This should survive all upgrades of the distribution but it should not change the behavior of apt-get (aside from running the command before doing anything else). As bonus, it could parse the command line arguments to only run the command when it is truly needed.

(This answer builds upon the answer from Mohammad Etemaddar, merged with the feedback from muru)

2

You can use an "alias" in the .bashrc file. For example, put that in your root .bashrc file:

alias apt-get='echo blahblah && apt-get'

Command-line arguments will be added automatically to the end of the alias.

Just replace echo blahblah by the command you need.

But in this case, it only works when you're executing commands as root (not sudo).

4
  • Is it possible to put this alias in normal user profile in order to use it by sudo? Commented May 19, 2015 at 22:25
  • 1
    Yes, I thik so. Try: alias apt-get='echo blahblah && sudo apt-get'. Then you only need to type in the terminal for example - apt-get update without sudo, and you'll be asked for a sudo password automatically.
    – Roman
    Commented May 19, 2015 at 22:33
  • it's true. of course then 'echo blahblah' won't work under su privileges. Commented May 19, 2015 at 22:39
  • 1
    It might be better to use a shell function or a script (in /usr/local/bin or ~/bin), because aliases don't handle arguments well. Commented May 25, 2015 at 1:38
1

First determine where is apt-get using whereis apt-get; I will assume it's in /usr/bin/apt-get

as muru says, You can create a script named apt-get in /usr/local/bin/ which is before /usr/bin in Debian and Ubuntu $PATH. Then put the following code to it (/usr/local/bin/apt-get):

#!/bin/bash
commands to run before apt-get
/usr/bin/apt-get "$@"

Thanks muru for offer as comment.

Other way:

Of course there's another way which is not better than previous one.

You can mv /usr/bin/apt-get /usr/bin/apt-get2

Then create a file in /usr/bin/apt-get with this content:

#!/bin/bash
commands to run before apt-get
apt-get2 "$@"

now chmod +x /usr/bin/apt-get

5
  • does this survive a dist-upgrade? Commented May 23, 2015 at 16:31
  • Yes. $@ causes script to work with every arguments. Commented May 24, 2015 at 17:05
  • 6
    Eek. If you want to create a replacement, put it in /usr/local/bin, which comes before /usr/bin in the default PATH in Debian and Ubuntu.
    – muru
    Commented May 24, 2015 at 17:33
  • 4
    This is really bad advice, sorry. (a) The apt-get executable is located in /usr/bin/apt-get, not sbin. (b) Don't mess with system commands. As muru says, you can create a local override in /usr/local/bin, though even that is not a good solution. Commented May 27, 2015 at 9:56
  • @muru /usr/local/bin sounds like a possible way to go - I hadn’t thought of that. Thank you! Commented May 29, 2015 at 13:41
0

Try an alias in the .bashrc file. It only works when logged in to the account that the file corresponds to. The syntax of an alias is:

alias newcommand='command1; command2; command3' So your line might look a bit like this:

alias apt-get='firstcommand; apt-get'

Or this:

alias apt-get='firstcommand && apt-get'

With the second, apt-get will only execute if firstcommand succeeds.

1
  • Aside from clarifying the root / normal user issue, this is essentially a reiteration of the first answer. Commented May 24, 2015 at 18:55

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .