Pourquoi xargs fait-il avorter apt-get?

17

J'essaie de supprimer une liste de packages d'un fichier. J'utilise la commande suivante:

cat packages | xargs sudo apt-get remove

packagesest mon fichier contenant une liste de packages que je souhaite supprimer. Tout semble fonctionner, mais apt-getabandonne au lieu de me laisser choisir oui ou non.

Je sais que je peux contourner cela avec l' -yoption, mais je voudrais savoir pourquoi cela se produit et comment puis-je conserver le choix interactif.

subb
la source
Comment ça "marche bien" quand on dirait que ça ne marche pas du tout? À quoi ressemble une entrée dans votre fichier? As-tu essayé sudo xargs --arg-file packages apt-get remove?
pause jusqu'à nouvel ordre.
Eh bien, cela "fonctionne" car apt-get en arrive au point de supprimer les bons packages. Cela dit, --arg-file était ce que je cherchais. Vous pouvez mettre cela dans une réponse et je l'accepterai. Merci!
subb

Réponses:

13
xargs -a packages sudo apt-get remove

dirigera xargspour lire les arguments de packages, et ainsi il laissera stdin sans souci.

éphémère
la source
10

Une solution plus générale serait

 sudo apt-get remove `cat packages`

où vous aurez un problème si la liste des packages est vraiment longue .

La raison pour laquelle cela ne fonctionne pas est qu'apt-get essaie de lire votre confirmation à partir de l'entrée standard à laquelle - à cause du tuyau - est attachée cat. Au contraire, sudofait la bonne chose en demandant votre mot de passe en ouvrant / dev / tty directement. Apt devrait le faire, mais apparemment pas.

msw
la source
L'entrée standard de xargs est connectée au tube de cat, mais le processus démarré par xargs a son entrée standard provenant de / dev / null. C'est le comportement de xargs. Démonstration simple:echo "" | xargs ls -l /dev/self/fd
Juliano
1
@mws: Non, apt-getne devrait pas ouvrir /dev/tty. Sinon, vous ne pourriez pas faire des choses comme yes | apt-get. Les mots de passe sont à peu près le seul cas où la lecture /dev/ttyest la bonne chose, et même cela est discutable.
Gilles 'SO- arrête d'être méchant'
Merci pour les commentaires, les deux sont corrects et mieux pensés que ma réponse slap-dash, que je vais laisser non modifiée afin que les commentaires aient toujours du sens.
msw
Je vois. Y a-t-il une différence entre ceci et xargs -un nom de fichier, comme le suggère ephemient?
subb
Oui, l'utilisation éphémère de l' --arg-fileoption est encore meilleure pour le cas spécifique, c'est pourquoi je l'ai votée positivement. Pour les nombreuses commandes qui n'ont pas une telle option, la métaphore backtick-cat a toujours ses utilisations.
msw
2

Parce que apt-getsupprime plusieurs packages et doit donc confirmer l'action. Puisqu'il lit à STDINpartir d'un tuyau et n'est pas connecté au terminal, il suppose automatiquement No.

Une autre façon de se déplacer est d'ajouter APT::Get::Assume-Yesà apt.conf.

bahamat
la source
2

Apparemment, xargs redirige STDIN, ce qui confond apt-get à supposer qu'il fonctionne en mode non interactif.

J'utiliserais probablement quelque chose comme

sudo apt-get remove $(cat packages)

pour éviter d'utiliser xargs du tout.

("--arg-file" n'est ni dans apt-get (8) man ni dans mon vocabulaire actif).

Onlyjob
la source
1

Pour contourner.

Avec GNU xargs et ksh / zsh / bash:

sudo xargs -r --arg-file <(cat packages) apt-get remove

(bien sûr, si la commande est juste cat, vous pouvez la remplacer <(cat packages)par packages.

Ou:

< packages sudo xargs sh -c 'exec apt-get remove "$@" < /dev/tty' sh

Selon le format du fichier "packages" (xargs attend une liste d'arguments séparés par des blancs et traite les guillemets ( ", 'et \), alors $(...)qu'il ne traite pas les guillemets et développe les modèles de globalisation), vous pouvez également faire:

sudo apt-get remove $(cat packages)

Mais veuillez noter que de nombreux systèmes d'exploitation ont une limite sur la longueur d'une ligne de commande, de sorte que cela peut ne pas fonctionner si la liste est grande (tandis que xargscontournera le problème en exécutant plusieurs apt-getcommandes).

Stéphane Chazelas
la source
0

Je peux me tromper, mais vous pouvez essayer cela et voir si cela fonctionne:

yes | sudo apt-get remove $(cat packages)
fromnaboo
la source