Comment exécuter une commande avant de télécharger avec apt-get?

8

Comment puis-je exécuter une commande avant que apt-get ne commence à télécharger un package?

Je connais le hook dpkg pré-invoqué ( hook un script pour apt-get ), mais cela semble être exécuté après le téléchargement.

$ 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/

Ce dont nous avons besoin, c'est d'exécuter une commande avant le téléchargement. Plus exactement: le script doit s'exécuter après avoir appelé apt-get mais avant qu'apt-get accède à toute ressource en ligne.

Y a-t-il quelque chose comme un crochet de pré-téléchargement?

Il est important que l'installation puisse se faire sans avoir à remplacer le script apt-get (et sans rien faire qui pourrait être annulé par une mise à jour).

Arne Babenhauserheide
la source
2
Vous pourriez déclarer une fonction nommée apt-getqui appellerait elle-même le réel apt-get. Selon l'étendue que vous souhaitez qu'elle ait, la fonction peut être déclarée dans /etc/profileou ~/.profileou ~/.bashrc.
user43791
Que signifie exactement "Le script doit s'exécuter après avoir appelé apt-get mais avant qu'apt-get accède à une ressource en ligne"? Quelle partie de la production apt-get doit être exécutée avant que votre hook puisse s'exécuter correctement?
2015
@jthill nous devons déclencher le téléchargement d'une URL donnée avant d'accéder à toute autre URL. La raison en est que nous téléchargeons depuis freenet (magasin de données anonyme décentralisé utilisé comme dépôt deb) et nous voulons déclencher une recherche agressive pour la version la plus récente avant de télécharger quoi que ce soit.
Arne Babenhauserheide
Dans les commentaires, vous demandez comment remplacer une commande système d'une manière qui ne peut pas être contournée et ne peut pas être supprimée même par le programme d'installation du système. Vous demandez comment rooter le système.
2015
Il serait utile de décrire votre cas d'utilisation. Ou en d'autres termes, qu'essayez-vous de faire?
Faheem Mitha

Réponses:

5

Qu'en est-il de l'utilisation des crochets apt pré / post-invocation?

Essentiellement, il est similaire aux hooks dpkg pré / post-invocation mais pour apt (qui, je suppose, est en fait le plus important dans votre scénario d'utilisation). AFAIK il y en a d'autres mais je n'ai utilisé que comme ça.

Par exemple

$ sudo cat /etc/apt/apt.conf.d/05new-hook
APT::Update::Pre-Invoke {"your-command-here"};
Jeremy Davis
la source
Apt ne fournit cependant pas de hook de pré-appel pour la mise à niveau ou l'installation, donc cela ne fonctionne que pour apt-get update.
Andrew Domaszek
C'est vrai, mais je répondais précisément à la question! :) Vous pouvez utiliser des crochets dpkg (selon l'OP) pour tout ce qui nécessite des ajustements avant / après l'installation.
Jeremy Davis
En quelque sorte; en supposant que la mise à jour est toujours exécutée avant la mise à niveau / l'installation. Accrocher toutes les commandes avant que l'accès au réseau ne se produise semble impossible avec les hooks apt actuellement (2017-05-17) disponibles. C'est toujours la meilleure réponse pour les scripts, mais cela n'aide pas pour des choses comme les scripts de mise à jour automatique existants.
Andrew Domaszek
Oh ok, je vous comprends maintenant. Désolé; oui, vous avez un très bon point. Vous pouvez donc modifier la mise à jour d'apt-get, mais l'installation d'apt-get sera toujours téléchargée avant que les hooks de dpkg ne s'exécutent?! Hmmm, ça craint vraiment!
Jeremy Davis
Qu'est-ce que tu essaies de faire? Si vous voulez des mises à jour automatiques mais que vous installez uniquement à partir de dépôts spécifiques (par exemple la sécurité Debian), vous pouvez utiliser cronapt avec un script comme le script cronapt de TurnKey [1]. Divisez vos entrées sources.list en fichiers séparés; ceux dont vous souhaitez que les mises à jour automatiques se trouvent dans security.sources.list. [1] github.com/turnkeylinux/common/blob/master/conf/turnkey.d/…
Jeremy Davis
2

Déterminez d'abord où apt-get utilise whereis apt-getou which apt-get; Je suppose que c'est dans / usr / bin / apt-get

Créez ensuite un fichier dans / usr / local / bin / apt-get avec ce contenu:

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

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

Cela devrait survivre à toutes les mises à niveau de la distribution mais cela ne devrait pas changer le comportement d'apt-get (à part exécuter la commande avant de faire quoi que ce soit d'autre). En prime, il pourrait analyser les arguments de la ligne de commande pour exécuter la commande uniquement lorsque cela est vraiment nécessaire.

(Cette réponse s'appuie sur la réponse de Mohammad Etemaddar , fusionnée avec les commentaires de muru)

Arne Babenhauserheide
la source
2

Vous pouvez utiliser un "alias" dans le fichier .bashrc. Par exemple, mettez cela dans votre fichier racine .bashrc:

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

Les arguments de ligne de commande seront ajoutés automatiquement à la fin de l'alias.

Remplacez-le simplement echo blahblahpar la commande dont vous avez besoin.

Mais dans ce cas, cela ne fonctionne que lorsque vous exécutez des commandes en tant que root (pas sudo).

romain
la source
Est-il possible de mettre cet alias dans le profil utilisateur normal afin de l'utiliser par sudo?
Mohammad Etemaddar
1
Oui, je le pense. Essayez: alias apt-get='echo blahblah && sudo apt-get'. Ensuite, il vous suffit de taper le terminal par exemple - apt-get updatesans sudo, et un mot de passe sudo vous sera automatiquement demandé.
Roman
c'est vrai. bien sûr, alors 'echo blahblah' ne fonctionnera pas avec les privilèges su.
Mohammad Etemaddar
1
Il peut être préférable d'utiliser une fonction shell ou un script (dans /usr/local/binou ~/bin), car les alias ne gèrent pas bien les arguments.
Scott
1

Déterminez d'abord où apt-get est utilisé whereis apt-get; Je suppose que c'est dans / usr / bin / apt-get

comme le dit muru , vous pouvez créer un script nommé apt-getdans /usr/local/bin/lequel se trouve avant /usr/bindans Debian et Ubuntu $PATH. Ensuite, mettez-y le code suivant ( /usr/local/bin/apt-get):

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

Merci muru pour l'offre comme commentaire.

Autre moyen:

Bien sûr, il existe un autre moyen qui n'est pas meilleur que le précédent.

Vous pouvez mv /usr/bin/apt-get /usr/bin/apt-get2

Créez ensuite un fichier dans / usr / bin / apt-get avec ce contenu:

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

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

Mohammad Etemaddar
la source
cela survit-il à une mise à niveau dist?
Arne Babenhauserheide
Oui. $@fait fonctionner le script avec tous les arguments.
Mohammad Etemaddar
6
Eek. Si vous voulez créer un remplacement, mettez-le /usr/local/bin, qui précède /usr/bindans le PATH par défaut dans Debian et Ubuntu.
muru
3
C'est vraiment un mauvais conseil, désolé. (a) L' apt-getexécutable se trouve dans /usr/bin/apt-get, non sbin. (b) Ne jouez pas avec les commandes du système. Comme le dit Muru, vous pouvez créer un remplacement local /usr/local/bin, même si ce n'est pas une bonne solution.
Faheem Mitha
@muru / usr / local / bin sonne comme un chemin possible - je n'y avais pas pensé. Je vous remercie!
Arne Babenhauserheide
0

Essayez un alias dans le .bashrcfichier. Cela ne fonctionne que lorsque vous êtes connecté au compte auquel le fichier correspond. La syntaxe d'un alias est:

alias newcommand='command1; command2; command3' Votre ligne pourrait donc ressembler un peu à ceci:

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

Ou ca:

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

Avec le second, apt-getne s'exécutera qu'en cas de firstcommandsuccès.

Will Dereham
la source
Outre la clarification du problème de l'utilisateur root / normal, il s'agit essentiellement d'une réitération de la première réponse.
G-Man dit `` Réintègre Monica ''