Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm trying to remove a list of packages from a file. I'm using the following command:

cat packages | xargs sudo apt-get remove

packages is my file containing a list of packages I want to remove. Everything appears to work, but apt-get aborts instead of letting me choose yes or no.

I know I can get around this with the -y option, but I would like to know why this is happening and how can I keep the interactive choice.

share|improve this question
    
How does it "work well" when it sounds like it doesn't work at all? What does an entry in your file look like? Have you tried sudo xargs --arg-file packages apt-get remove? –  Dennis Williamson Nov 15 '10 at 6:00
    
Well, it kind of "works" because apt-get gets to the point of removing the right packages. That said, --arg-file was what I was looking for. You can put that in an answer and I will accept it. Thanks! –  subb Nov 15 '10 at 6:13
add comment

6 Answers 6

A more general solution would be

 sudo apt-get remove `cat packages`

where you will have a problem if the list of packages is really long.

The reason that it isn't working is that apt-get is trying to read your confirmation from the standard input which - because of the pipe - is attached to cat. Contrariwise, sudo does the Right Thing by asking your password by opening /dev/tty directly. Apt should do this but apparently doesn't.

share|improve this answer
    
The standard input of xargs is connected to the pipe from cat, but the process started by xargs has its standard input coming from /dev/null. This is the behavior of xargs. Simple demonstration: echo "" | xargs ls -l /dev/self/fd –  Juliano Nov 15 '10 at 15:10
1  
@mws: No, apt-get shouldn't open /dev/tty. Otherwise you couldn't do things like yes | apt-get. Passwords are pretty much the only case where reading from /dev/tty is the right thing, and even that much is debatable. –  Gilles Nov 15 '10 at 20:21
    
Thanks for the comments, both are correct and better thought than my slap-dash response, which I'm going to leave un-edited so that the comments still make sense. –  msw Nov 16 '10 at 4:14
    
I see. Is there any difference between this and xargs -a filename, like ephemient is suggesting? –  subb Nov 17 '10 at 6:23
    
Yes, ephimemient's use of the --arg-file option is even better for the specific case which is why I upvoted it. For the many commands that don't have such an option the backtick-cat metaphor still has its uses. –  msw Nov 17 '10 at 14:09
add comment
xargs -a packages sudo apt-get remove

will direct xargs to read arguments from packages, and so it will leave stdin unmolested.

share|improve this answer
add comment

Because apt-get is removing more than one package, and therefore must confirm the action. Since it's reading STDIN from a pipe and is not connected to the terminal it auto assumes No.

Another way to get around this is to add APT::Get::Assume-Yes to apt.conf.

share|improve this answer
add comment

Apparently xargs redirects STDIN which confuses apt-get to assume that it is running in non-interactive mode.

I would probably use something like

sudo apt-get remove $(cat packages)

to avoid using xargs at all.

("--arg-file" is neither in apt-get(8) man nor in my active vocabulary).

share|improve this answer
add comment

To work around.

With GNU xargs and ksh/zsh/bash:

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

(of course, if the command is just cat, then you can replace <(cat packages) with packages.

Or:

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

Depending on the format of the "packages" file (xargs is expecting a blank-separated list of arguments and processes quotes (", ' and \), while $(...) doesn't process quotes and expands globbing patterns), you could also do:

sudo apt-get remove $(cat packages)

But please note that many operating systems have a limit on the length of a command line, so that may not work if the list is big (while xargs will work around the issue by running several apt-get commands).

share|improve this answer
add comment

I may be wrong, but you can try this and see if it works:

yes | sudo apt-get remove $(cat packages)
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.