Perché xargs causa l'annullamento di apt-get?


17

Sto cercando di rimuovere un elenco di pacchetti da un file. Sto usando il seguente comando:

cat packages | xargs sudo apt-get remove

packagesè il mio file contenente un elenco di pacchetti che voglio rimuovere. Tutto sembra funzionare, ma si apt-getinterrompe invece di farmi scegliere Sì o No.

So che posso aggirare questo con l' -yopzione, ma vorrei sapere perché questo sta accadendo e come posso mantenere la scelta interattiva.


Come "funziona bene" quando sembra che non funzioni affatto? Che aspetto ha una voce nel tuo file? Ci hai provato sudo xargs --arg-file packages apt-get remove?
In pausa fino a nuovo avviso.

Bene, in un certo senso "funziona" perché apt-get arriva al punto di rimuovere i pacchetti giusti. Detto questo, --arg-file era quello che stavo cercando. Puoi inserirlo in una risposta e lo accetterò. Grazie!
subb

Risposte:


13
xargs -a packages sudo apt-get remove

dirige xargsa leggere gli argomenti da packages, e quindi lascerà stdin non molestato.


10

Una soluzione più generale sarebbe

 sudo apt-get remove `cat packages`

dove avrai un problema se l'elenco dei pacchetti è davvero lungo .

Il motivo per cui non funziona è che apt-get sta cercando di leggere la conferma dall'input standard a cui - a causa della pipe - è collegato cat. Al contrario, sudofa la cosa giusta chiedendo la password aprendo / dev / tty direttamente. Apt dovrebbe farlo ma a quanto pare no.


L'input standard di xargs è collegato al pipe da cat, ma il processo avviato da xargs ha il suo input standard proveniente da / dev / null. Questo è il comportamento di xargs. Dimostrazione semplice:echo "" | xargs ls -l /dev/self/fd
Juliano,

1
@mws: No, apt-getnon dovrebbe aprire /dev/tty. Altrimenti non potresti fare cose del genere yes | apt-get. Le password sono praticamente l'unico caso in cui leggere /dev/ttyè la cosa giusta, e anche questo è discutibile.
Gilles 'SO- smetti di essere malvagio' il

Grazie per i commenti, entrambi sono corretti e meglio pensati della mia risposta da schiaffo, che lascerò non modificata in modo che i commenti abbiano ancora senso.
msw,

Vedo. C'è qualche differenza tra questo e xargs -a nome file, come sta suggerendo ephemient?
subb il

Sì, l'uso di ephimemient --arg-filedell'opzione è ancora migliore per il caso specifico ed è per questo che l'ho votato. Per i numerosi comandi che non dispongono di tale opzione, la metafora backtick-cat ha ancora i suoi usi.
msw,

2

Perché apt-getsta rimuovendo più di un pacchetto e quindi deve confermare l'azione. Poiché sta leggendo STDINda una pipe e non è collegato al terminale, si assume automaticamente No.

Un altro modo per aggirare questo è aggiungere APT::Get::Assume-Yesa apt.conf.


2

Apparentemente xargs reindirizza STDIN che confonde apt-get supponendo che sia in esecuzione in modalità non interattiva.

Probabilmente userei qualcosa del genere

sudo apt-get remove $(cat packages)

per evitare di usare xargs.

("--arg-file" non è né in apt-get (8) man né nel mio vocabolario attivo).


1

Per aggirare.

Con GNU xargs e ksh / zsh / bash:

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

(ovviamente, se il comando è giusto cat, puoi sostituirlo <(cat packages)con packages.

O:

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

A seconda del formato del file "pacchetti" (xargs aspetta un elenco separato di argomenti e processi preventivi ( ", 'e \), mentre $(...)non citazioni di processo e si espande globbing modelli), si potrebbe anche fare:

sudo apt-get remove $(cat packages)

Ma tieni presente che molti sistemi operativi hanno un limite sulla lunghezza di una riga di comando, quindi potrebbe non funzionare se l'elenco è grande (mentre xargsrisolverà il problema eseguendo diversi apt-getcomandi).


0

Potrei sbagliarmi, ma puoi provare questo e vedere se funziona:

yes | sudo apt-get remove $(cat packages)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.