# Writing to STDOUT after closing controlling terminal

**URL:** <https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830>\
**Category:** Ruby\
**Created:** [September 21, 2009, 3:14am UTC](https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830 "2009-09-21T03:14:28Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [September 21, 2009, 3:14am UTC](https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830/1 "2009-09-21T03:14:28Z")

</div>

Hi,  
I don’t know if this is a dumb question or not (I hope it isn’t), but it  
seems to me there’s something wrong here. I’ve been using Ruby for a  
long time now, and I never noticed this (maybe it wasn’t working like  
this in the past), and it just seems odd.  
If I write the following code:

sleep(5)  
begin  
puts ‘hi!’  
rescue  
File.open(‘output’, ‘w’) {|io| io.puts $!.message }  
end

And execute it in Ruby 1.9.1p243 in a graphical terminal (e.g.: konsole)  
as a foreground process I obviously get this:

$ ./test.rb  
hi!

And there’s no “output” file created sine no exception was raised.

Now, If I do:  
$ ./test.rb &  
[1] 28137  
and immediately close konsole, 5 seconds later I get:  
$ cat output  
Input/output error -

Is this ok? I seems to me that one shouldn’t have to care if the  
controlling terminal is closed when doing “puts” to avoid this exception  
from ending my ruby process.

As a sidenote, with Ruby 1.8.7p174 the process doesn’t get any  
exception. If now I write (to check for normal process completion):

sleep(5)  
begin  
puts ‘hi!’  
File.open(‘output2’, ‘w’) {|io| io.puts ‘ok’ }  
rescue  
File.open(‘output’, ‘w’) {|io| io.puts $!.message }  
end  
with

and execute it as before, I get the “output2” file with the “ok” string  
in it.

Is this a bug? a feature?

Thank you,  
Matt

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [September 21, 2009, 3:45am UTC](https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830/2 "2009-09-21T03:45:51Z")

</div>

As far as killing the controlling terminal is concerned, AFAIK it’s  
standard  
Unix practice. If you want the process to stay alive even if you kill  
the  
terminal, you either redirect its stdin/stdout or use nohup.  
-Mario.

–  
I want to change the world but they won’t give me the source code.

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [September 21, 2009, 3:49am UTC](https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830/3 "2009-09-21T03:49:55Z")

</div>

Mario C. wrote:

> As far as killing the controlling terminal is concerned, AFAIK it’s  
> standard  
> Unix practice. If you want the process to stay alive even if you kill  
> the  
> terminal, you either redirect its stdin/stdout or use nohup.  
> -Mario.
> 
> –  
> I want to change the world but they won’t give me the source code.

I know it’s not enough justification, but doing an “echo 1” from a  
backgrounded bash script process doesn’t kill the script. I understand  
that you should redirect STDOUT, but in Ruby should programmers really  
need to concern about this?  
Or maybe this would translate to the users of that Ruby program to be  
forced to redirect STDOUT and STDERR to /dev/null or something (which  
also seems a bit weird to me).

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [September 21, 2009, 3:21pm UTC](https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830/4 "2009-09-21T15:21:52Z")

</div>

On Sunday 20 September 2009 08:49:56 pm Matt B. wrote:

> I know it’s not enough justification, but doing an “echo 1” from a  
> backgrounded bash script process doesn’t kill the script.

That’s because your script is badly written. Try this script:

#!/bin/sh  
sleep 5  
echo hi || echo $! \> output

This has exactly the same behavior as your Ruby script, except that  
you’re  
only capturing the return value of that first echo command.

In other words: In a shell script (bash or otherwise), the ‘echo’  
command does  
indeed get killed. It’s just that by default, shell scripts ignore the  
return  
values, which means errors are silently eaten. Ruby, on the other hand,  
raises  
an exception when something goes wrong.

I don’t like silent errors, so I usually write shell scripts that look  
more  
like this:

#!/bin/sh  
first line &&  
second line &&  
third line &&  
fourth line

That way, the script dies at the first error, unless I explicitly handle  
it.

> I understand  
> that you should redirect STDOUT, but in Ruby should programmers really  
> need to concern about this?

If you don’t want to be concerned about this, abstract it away with some  
sort  
of logging class. I’m glad Ruby has the same behavior as any other  
language,  
when it comes to basic Unix semantics like this – and I’m glad my  
output  
doesn’t just silently get eaten when I close the terminal.

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [September 21, 2009, 4:36pm UTC](https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830/5 "2009-09-21T16:36:29Z")

</div>

David M. wrote:

> On Sunday 20 September 2009 08:49:56 pm Matt B. wrote:
> 
> > I know it’s not enough justification, but doing an “echo 1” from a  
> > backgrounded bash script process doesn’t kill the script.
> 
> That’s because your script is badly written. Try this script:
> 
> #!/bin/sh  
> sleep 5  
> echo hi || echo $! \> output
> 
> This has exactly the same behavior as your Ruby script, except that  
> you’re  
> only capturing the return value of that first echo command.
> 
> In other words: In a shell script (bash or otherwise), the ‘echo’  
> command does  
> indeed get killed. It’s just that by default, shell scripts ignore the  
> return  
> values, which means errors are silently eaten. Ruby, on the other hand,  
> raises  
> an exception when something goes wrong.

Ok, I didn’t realized that about the bash script.  
So, this means that this difference between ruby 1.8 and ruby 1.9 is a  
feature?  
I guess that I should then use nohup if I don’t want to think about this  
issue when writing other Ruby programs.

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [September 21, 2009, 4:15pm UTC](https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830/6 "2009-09-21T16:15:42Z")

</div>

On 2009-09-21, David M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I don’t like silent errors, so I usually write shell scripts that look more  
> like this:

You might use “set -e”. I don’t, but I check exactly those errors I  
care  
about. (I don’t necessarily care about loss of output.)

-s

---

<div class="post-metadata">

**Author:** ![burrowsm](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d78d45/32.png) [@burrowsm](https://www.ruby-forum.com/u/burrowsm)\
**Post date:** [September 22, 2009, 2:39am UTC](https://www.ruby-forum.com/t/writing-to-stdout-after-closing-controlling-terminal/175830/7 "2009-09-22T02:39:47Z")

</div>

On Monday 21 September 2009 09:36:31 am Matt B. wrote:

> So, this means that this difference between ruby 1.8 and ruby 1.9 is a  
> feature?

In my opinion.

> I guess that I should then use nohup if I don’t want to think about this  
> issue when writing other Ruby programs.

Depends what you’re using the output for. I would use some sort of  
logger, if  
you can’t count on stdout being redirected.
