Thanks for the excellent information, Robert.  I did figure out that the 
problem with rm -i is not just with the newline, but probably with the 
kind of thing you are describing -- grep won't write to stdout until it 
either has the newline or some kind of flush signal.  I agree with your 
conclusion -- no more "rm -i" in shell scripts.

Mike


On Tue, 15 Jun 2010, Robert Nesius wrote:

> On Tue, Jun 15, 2010 at 12:49 AM, Mike Miller <mbmiller+l at gmail.com> wrote:
>
>> On Tue, 15 Jun 2010, Mike Miller wrote:
>>
>>> Here's something safe and easy that anyone can try at home:
>>>
>>> ( touch foo ; echo bar ; rm -i foo ) 2>&1
>>>
>>> ( touch foo ; echo bar ; rm -i foo ) 2>&1 | grep -v bar
>>>
>>> ( touch foo ; echo bar ; rm -i foo ) 2>&1 | grep -v baz
>>>
>>> See what I mean?  Apparently, rm can't send its stderr until the grep
>>> command has completed, so it just sits there waiting for input.
>>
>>
>> If I use cat instead of grep, it's fine.  It has something to do with 
>> the newline: rm -i doesn't send a newline with the prompt.  Compare the 
>> behavior of these:
>>
>
> When doing I/O, remember that underneath the printf's and readln's are 
> "read" and "write" system calls, and that these work against buffers. 
> Output buffers don't flush until they see a newline, EOF marker, or the 
> file handle is closed (causing the OS to flush the buffer as it is 
> deallocated), or the filehandle is the argument of a system call to 
> force a flush (flush()?).  Correspondingly, a flushed buffer linked to a 
> file on disk is in turn not yet safely written - sync or fsync commands 
> are the safe bet there.
>
> A lot of times you will see buffers flush as a program exits because 
> many programmers don't explicitly close their file handles and so it's 
> the process-cleanup process that flushes buffers prior to deallocating 
> the filehandles and - if necessary - the buffers themselves.
>
> I believe there are ways to configure a filehandle to immediately 
> flush-through everything that is written.  Of course - that leads to 
> many more interrupts and is not as efficient, but it is possible. I'm 
> not sure how to do that though - I haven't had to deal with I/O at that 
> level for a long time.
>
>
>> Maybe we would be better off if the prompt from "rm -i" sent a newline. 
>> On the other hand, maybe I should just never use "rm -i" in a script. 
>> There has to be a better way.
>>
>>
> I would not use rm -i in a script, ever, mainly just for style reasons. 
> For example, it's possible on some unix implementations your script 
> would work as expected because that implementation of rm does send a 
> new-line, but then when moving the script somewhere else - whoah - gnu's 
> rm doesn't send a new-line - whoops!  And maybe some rm's write to 
> stdout, and some to stderr.  I'd wrap that rm with my own I/O management 
> code that is (hopefully) more portable and trustworthy.
>
> -Rob