Tại sao xargs gây ra apt-get để hủy bỏ?


17

Tôi đang cố gắng xóa danh sách các gói khỏi tệp. Tôi đang sử dụng lệnh sau:

cat packages | xargs sudo apt-get remove

packageslà tập tin của tôi chứa danh sách các gói tôi muốn xóa. Tất cả mọi thứ dường như làm việc, nhưng apt-gethủy bỏ thay vì để tôi chọn có hoặc không.

Tôi biết tôi có thể giải quyết vấn đề này với -ytùy chọn, nhưng tôi muốn biết tại sao điều này xảy ra và làm thế nào tôi có thể giữ lựa chọn tương tác.


Làm thế nào để nó "hoạt động tốt" khi nghe có vẻ như nó không hoạt động? Một mục trong tập tin của bạn trông như thế nào? Bạn đã thử sudo xargs --arg-file packages apt-get removechưa
Tạm dừng cho đến khi có thông báo mới.

Vâng, đó là loại "hoạt động" bởi vì apt-get đạt đến điểm loại bỏ các gói phù hợp. Điều đó nói rằng, --arg-file là những gì tôi đang tìm kiếm. Bạn có thể đặt nó trong một câu trả lời và tôi sẽ chấp nhận nó. Cảm ơn!
subb

Câu trả lời:


13
xargs -a packages sudo apt-get remove

sẽ trực tiếp xargsđể đọc các đối số từ đó packages, và vì vậy nó sẽ khiến stdin không bị biến đổi.


10

Một giải pháp tổng quát hơn sẽ là

 sudo apt-get remove `cat packages`

nơi bạn sẽ gặp vấn đề nếu danh sách các gói thực sự dài .

Lý do nó không hoạt động là vì apt-get đang cố đọc xác nhận của bạn từ đầu vào tiêu chuẩn - vì đường ống - được đính kèm cat. Ngược lại, sudothực hiện quyền bằng cách hỏi mật khẩu của bạn bằng cách mở / dev / tty trực tiếp. Apt nên làm điều này nhưng dường như không.


Đầu vào tiêu chuẩn của xargs được kết nối với đường ống từ cat, nhưng quá trình bắt đầu bởi xargs có đầu vào tiêu chuẩn đến từ / dev / null. Đây là hành vi của xargs. Trình diễn đơn giản:echo "" | xargs ls -l /dev/self/fd
Juliano

1
@Ms: Không, apt-getkhông nên mở /dev/tty. Nếu không, bạn không thể làm những việc như thế yes | apt-get. Mật khẩu là khá nhiều trường hợp duy nhất mà việc đọc từ đó /dev/ttylà điều đúng đắn, và thậm chí điều đó còn gây tranh cãi.
Gilles 'SO- ngừng trở nên xấu xa'

Cảm ơn các bình luận, cả hai đều đúng và suy nghĩ tốt hơn so với phản hồi tát của tôi, điều mà tôi sẽ không chỉnh sửa để các bình luận vẫn có ý nghĩa.
msw

Tôi hiểu rồi. Có sự khác biệt nào giữa tên này và xargs - một tên tệp, như ephemient đang đề xuất không?
subb

Có, việc sử dụng --arg-filetùy chọn của ephimemient thậm chí còn tốt hơn cho trường hợp cụ thể, đó là lý do tại sao tôi nâng cấp nó. Đối với nhiều lệnh không có tùy chọn như vậy, phép ẩn dụ backtick-cat vẫn có cách sử dụng.
msw

2

Bởi vì apt-getđang loại bỏ nhiều hơn một gói, và do đó phải xác nhận hành động. Vì nó đọc STDINtừ một đường ống và không được kết nối với thiết bị đầu cuối, nó tự động giả định No.

Một cách khác để khắc phục điều này là thêm APT::Get::Assume-Yesvào apt.conf.


2

Rõ ràng xargs chuyển hướng STDIN gây nhầm lẫn cho apt-get khi cho rằng nó đang chạy ở chế độ không tương tác.

Tôi có thể sẽ sử dụng một cái gì đó như

sudo apt-get remove $(cat packages)

để tránh sử dụng xargs cả.

("--arg-file" không phải ở người đàn ông apt-get (8) cũng như trong vốn từ vựng hoạt động của tôi).


1

Để làm việc xung quanh.

Với GNU xargs và ksh / zsh / bash:

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

(tất nhiên, nếu lệnh chỉ là cat, thì bạn có thể thay thế <(cat packages)bằng packages.

Hoặc là:

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

Tùy thuộc vào định dạng của tệp "gói" (xargs đang mong đợi một danh sách các đối số và quy trình trích dẫn được phân tách trống ( ", '\), trong khi $(...)không xử lý dấu ngoặc kép và mở rộng các mẫu hình cầu), bạn cũng có thể làm:

sudo apt-get remove $(cat packages)

Nhưng xin lưu ý rằng nhiều hệ điều hành có giới hạn về độ dài của dòng lệnh, do đó có thể không hoạt động nếu danh sách lớn (trong khi xargssẽ khắc phục sự cố bằng cách chạy một số apt-getlệnh).


0

Tôi có thể sai, nhưng bạn có thể thử điều này và xem nếu nó hoạt động:

yes | sudo apt-get remove $(cat packages)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.