Чому xargs спричиняє аборт apt-get аборту?


17

Я намагаюся видалити список пакетів з файлу. Я використовую таку команду:

cat packages | xargs sudo apt-get remove

packages- мій файл, що містить перелік пакунків, які я хочу видалити. Все, здається, працює, але apt-getперериває, замість того, щоб дати мені вибір так чи ні.

Я знаю, що можу обійти це за допомогою -yваріанту, але хотів би знати, чому це відбувається і як я можу дотримати інтерактивний вибір.


Як це "добре працює", коли здається, що він зовсім не працює? Як виглядає запис у вашому файлі? Ви пробували sudo xargs --arg-file packages apt-get remove?
Призупинено до подальшого повідомлення.

Що ж, це "працює", тому що apt-get потрапляє в точку видалення потрібних пакетів. Це сказало, - arg-файл - це те, що я шукав. Ви можете поставити це у відповідь, і я прийму це. Спасибі!
субб

Відповіді:


13
xargs -a packages sudo apt-get remove

буде направляти xargsна читання аргументів з packages, і тому він залишить незмінним stdin.


10

Більш загальним було б рішення

 sudo apt-get remove `cat packages`

де у вас виникнуть проблеми, якщо список пакетів дійсно довгий .

Причина, що вона не працює, полягає в тому, що apt-get намагається прочитати ваше підтвердження зі стандартного вводу, до якого - через трубу - додається cat. Навпаки, sudoчи робить правильну річ, запитуючи свій пароль, відкривши / dev / tty безпосередньо. Apt повинен це зробити, але, мабуть, ні.


Стандартний вхід xargs підключений до труби з cat, але процес, розпочатий xargs, має стандартний вхід, що надходить від / dev / null. Така поведінка xargs. Проста демонстрація:echo "" | xargs ls -l /dev/self/fd
Джуліано

1
@mws: Ні, apt-getне слід відкривати /dev/tty. Інакше ти не можеш робити подібні речі yes | apt-get. Паролі - це майже єдиний випадок, коли читання з них /dev/tty- це правильна річ, і навіть це багато іншого є дискусійним.
Жил "ТАК - перестань бути злим"

Дякую за коментарі, обидва є коректними та кращими думками, ніж моя відповідь на штрих-тире, яку я залишаю не відредагованою, щоб коментарі все-таки мали сенс.
msw

Я бачу. Чи є якась різниця між цим і xargs -іменем файлу, як пропонує ephemient?
субб

Так, використання --arg-fileваріанту ephimemient ще краще для конкретного випадку, тому я його схвалив. Для багатьох команд, у яких немає такої опції, метафора backtick-cat все ще має своє використання.
msw

2

Тому що apt-getце видалення більше одного пакету, і тому потрібно підтвердити дію. Оскільки він читає STDINз труби і не підключений до терміналу, він автоматично передбачає No.

Інший спосіб обійти це , щоб додати APT::Get::Assume-Yesдо apt.conf.


2

Мабуть, xargs переспрямовує STDIN, що плутає apt-get, щоб припустити, що він працює в неінтерактивному режимі.

Я, мабуть, використовував щось подібне

sudo apt-get remove $(cat packages)

щоб взагалі не використовувати xargs.

("--arg-file" не є ні в apt-get (8) man, ні в моїй активній лексиці).


1

Щоб обійтись.

З xargs GNU та ksh / zsh / bash:

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

(звичайно, якщо команда справедлива cat, то її можна замінити <(cat packages)на packages.

Або:

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

В залежності від формату файлу «пакети» (xargs очікує порожній список розділених аргументів і процесів лапки ( ", 'і \), а $(...)не виконує жодних котирування і розширюється підстановка моделей), ви також можете зробити:

sudo apt-get remove $(cat packages)

Але зауважте, що в багатьох операційних системах є обмеження по довжині командного рядка, тому це може не спрацювати, якщо список великий (в той час як xargsбуде вирішено проблему, виконавши кілька apt-getкоманд).


0

Я можу помилятися, але ви можете спробувати це і побачити, чи працює він:

yes | sudo apt-get remove $(cat packages)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.