Prevent sudo, apt-get, etc. from swallowing pasted input to STDIN?

Solution 1:

A way to both avoid the cut-and-paste problem, as well as safely run the commands in succession is to put them on the same line separated by && which will only execute the cp on the successful completion of the sudo apt-get install:

sudo apt-get install -y postfix && sudo cp ~/siteconfig/etc/postfix/main.cf /etc/postfix

Afterall, if the first command fails you probably don't want to continue executing the rest of the commands.

As for why the commands get swallowed when you paste multiple lines at once... when postfix gets installed it asks configuration questions with the debconf dialog frontend which is likely what's interfering with the cut-and-paste. Maybe a different front-end like readline or noninteractive would interfere less? Still, I would use the && method anyway since it is safer.

If you're installing postfix with your scripts it sounds like maybe you're trying to automate the install of new systems? If so, consider using preseeding as an option (here is some Ubuntu 11.10 specific documentation) or maybe use puppet?

Solution 2:

There is an outstanding bug report about this: Debian Bug report #728775 - apt-get unwarrantedly consumes input. The report says:

When apt-get is invoked in a way that involves actually installing a package, it reads any available data from standard input, regardless of actual need. This breaks the usual ability, at an interactive shell, to type the next command while the current one is running: apt-get consumes input that was intended for the shell. strace shows that the input is read by the top-level apt-get process, by read(2) from fd 0, in response to pselect(2).
...
It's in pkgDPkgPM::Go() in apt-pkg/deb/dpkgpm.cc. Further down the same function, there's a pselect loop which does match what I saw with strace. It reads from stdin conditional only upon (master >= 0 && !d->stdin_is_dev_null)

And in a response:

It's to avoid someone typing their next command while packages are downloading, but then that input being used as the answer to a prompt during installation.

A workaround for you, since you're already giving apt-get the -y option so presumably don't want it to ask questions or read responses, is to redirect stdin to /dev/null. When I do the following:

apt-get install -y gdb-doc < /dev/null

my typeahead during execution of the apt-get command is not flushed.