Warum führt XARGS zum Abbruch von Apt-Get?


17

Ich versuche, eine Liste von Paketen aus einer Datei zu entfernen. Ich benutze den folgenden Befehl:

cat packages | xargs sudo apt-get remove

packagesist meine Datei mit einer Liste von Paketen, die ich entfernen möchte. Alles scheint zu funktionieren, aber apt-getbricht ab, anstatt mich zwischen Ja und Nein wählen zu lassen.

Ich weiß, dass ich mit dieser -yOption umgehen kann, aber ich möchte wissen, warum dies geschieht und wie ich die interaktive Auswahl beibehalten kann.


Wie funktioniert es, wenn es so klingt, als würde es überhaupt nicht funktionieren? Wie sieht ein Eintrag in Ihrer Datei aus? Hast du es versucht sudo xargs --arg-file packages apt-get remove?
Bis auf weiteres angehalten.

Nun, es "funktioniert" irgendwie, weil apt-get dazu kommt, die richtigen Pakete zu entfernen. Trotzdem war --arg-file das, wonach ich gesucht habe. Sie können das in einer Antwort setzen, und ich werde es akzeptieren. Vielen Dank!
Subb

Antworten:


13
xargs -a packages sudo apt-get remove

wird direkt xargsArgumente aus lesen packages, und so wird stdin unbelästigt bleiben.


10

Eine allgemeinere Lösung wäre

 sudo apt-get remove `cat packages`

wo Sie ein Problem haben, wenn die Liste der Pakete wirklich lang ist .

Der Grund, warum es nicht funktioniert, ist, dass apt-get versucht, Ihre Bestätigung von der Standardeingabe zu lesen, die - aufgrund der Pipe - an die Pipe angehängt ist cat. Im Gegensatz dazu sudowird das Richtige getan, indem Sie Ihr Passwort durch direktes Öffnen von / dev / tty abfragen. Apt sollte das tun, aber anscheinend nicht.


Die Standardeingabe von xargs ist mit der Pipe von verbunden cat, aber der von xargs gestartete Prozess hat seine Standardeingabe von / dev / null. Dies ist das Verhalten von Xargs. Einfache Demonstration:echo "" | xargs ls -l /dev/self/fd
Juliano

1
@mws: Nein, apt-getsollte nicht öffnen /dev/tty. Sonst könnte man sowas nicht machen yes | apt-get. Passwörter sind so ziemlich der einzige Fall, bei dem das Lesen von /dev/ttyden Passwörtern das Richtige ist, und sogar so viel ist umstritten.
Gilles 'SO - hör auf, böse zu sein'

Vielen Dank für die Kommentare, beide sind korrekt und besser gedacht als meine Antwort mit einem Schlag, die ich unbearbeitet lassen werde, damit die Kommentare immer noch Sinn machen.
msw

Aha. Gibt es einen Unterschied zwischen diesem und dem Dateinamen xargs -a, wie es ephemient vorschlägt?
Subb

Ja, die Verwendung der --arg-fileOption durch ephimemient ist im konkreten Fall sogar noch besser, weshalb ich sie positiv bewertet habe. Für die vielen Befehle, die keine solche Option haben, hat die Backtick-Cat-Metapher noch ihre Verwendung.
msw

2

Weil apt-getmehr als ein Paket entfernt wird und daher die Aktion bestätigen muss. Da es STDINaus einer Pipe liest und nicht mit dem Terminal verbunden ist, geht es automatisch davon aus No.

Eine andere Möglichkeit, dies zu umgehen APT::Get::Assume-Yes, ist das Hinzufügen zu apt.conf.


2

Anscheinend leitet xargs STDIN um, was apt-get verwirrt davon auszugehen, dass es im nicht interaktiven Modus ausgeführt wird.

Ich würde wohl sowas benutzen

sudo apt-get remove $(cat packages)

um xargs überhaupt zu vermeiden.

("--arg-file" ist weder in apt-get (8) man noch in meinem aktiven Wortschatz enthalten).


1

Um das Problem zu umgehen.

Mit GNU xargs und ksh / zsh / bash:

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

(natürlich nur , wenn der Befehl gerade ist cat, dann können Sie ersetzen <(cat packages)mit packages.

Oder:

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

Je nach Format der „Pakete“ Datei (xargs ist eine durch Leerzeichen getrennte Liste von Argumenten und Prozesse zitiert erwarten ( ", 'und \), während $(...)nicht verarbeitet Zitate und erweitert Globbing Muster), können Sie auch tun:

sudo apt-get remove $(cat packages)

Beachten Sie jedoch, dass bei vielen Betriebssystemen die Länge einer Befehlszeile begrenzt ist, sodass dies möglicherweise nicht funktioniert, wenn die Liste groß ist (Sie können xargsdas Problem jedoch umgehen, indem Sie mehrere apt-getBefehle ausführen).


0

Ich kann mich irren, aber Sie können dies versuchen und sehen, ob es funktioniert:

yes | sudo apt-get remove $(cat packages)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.