Pourquoi Xargs provoque-t-il l'abandon de apt-get?

J'essaie de supprimer une list de packages d'un file. J'utilise la command suivante:

cat packages | xargs sudo apt-get remove 

packages est mon file contenant une list de packages que je veux supprimer. Tout semble fonctionner, mais apt-get abort au lieu de me laisser choisir oui ou non.

Je sais que je peux contourner cela avec l'option -y , mais j'aimerais savoir pourquoi cela se produit et comment puis-je garder le choix interactif.

 xargs -a packages sudo apt-get remove 

va diriger xargs pour lire les arguments des packages , et ainsi il laissera stdin non molé.

Une solution plus générale serait

  sudo apt-get remove `cat packages` 

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

Apt-get essaie de lire votre confirmation à partir de l'input standard qui – à cause de la pipe – est attachée à cat . Par contre, sudo fait la bonne chose en demandant votre mot de passe en ouvrant / dev / tty directement. Apt devrait le faire mais apparemment pas.

Apparemment, xargs redirige STDIN, ce qui confuse apt-get de supposer qu'il s'exécute en mode non-interactif.

Je voudrais probablement utiliser 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), ni dans mon vocabulaire actif).

Parce que apt-get supprime plus d'un package et doit donc confirmer l'action. Comme il lit STDIN partir d'un tuyau et n'est pas connecté au terminal, il suppose automatiquement No .

Une autre façon de contourner ceci est d'append APT::Get::Assume-Yes à apt.conf .

Pour contourner.

Avec GNU xargs et ksh / zsh / bash:

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

(bien sûr, si la command est juste cat , vous pouvez replace <(cat packages) par des packages .

Ou:

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

Xargs attend une list d'arguments et de process séparés par des espaces ( " , ' et \ ), tandis que $(...) ne traite pas les guillemets et ne développe pas les templates de globulation. vous pourriez aussi faire:

 sudo apt-get remove $(cat packages) 

Mais notez que de nombreux systèmes d'exploitation ont une limite sur la longueur d'une command line, ce qui peut ne pas fonctionner si la list est volumineuse (alors que xargs contournera le problème en exécutant plusieurs commands apt-get ).

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

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