Joe Van Dyk
9/26/2006 10:32:00 PM
On 9/26/06, Joe Van Dyk <joevandyk@gmail.com> wrote:
> On 9/26/06, Joe Van Dyk <joevandyk@gmail.com> wrote:
> > On 9/26/06, Gennady Bystritsky <Gennady.Bystritsky@quest.com> wrote:
> > > Joe Van Dyk wrote:
> > > > On 9/26/06, Joe Van Dyk <joevandyk@gmail.com> wrote:
> > > >> Hello,
> > > >>
> > > >> So, on linux, I'm forking a new Ruby process. I redirect stdout and
> > > >> stderr into a file and then I execute another program via 'system'.
> > > >
> > > > I should probably mention that the other program that's being executed
> > > > is rsh, which executes a command on a different machine.
> > >
> > > You either did not redirect stdout/stderr to a file properly, or
> > > something you execute tries to output directly to the controlling
> > > terminal (/dev/tty). You can disassosiate your spawned process from a
> > > controlling terminal, just to be sure (not with 'system' though):
> > >
> > > logfile = "my_log_file.log"
> > > pid = fork do
> > > File.open(logfile, 'w') do |_io|
> > > $stdout.reopen(_io)
> > > $stderr.reopen(_io)
> > > end
> > >
> > > Process.setsess # In this scenario disassociates the controlling
> > > # terminal until another tty device is open (will
> > > # become new controlling tty).
> > >
> > > exec "the_command_line_used_to_be_launched_by_system"
> > > end
> > >
> > > Process.waitpid pid
> >
> > I assume you mean Process.setsid?
> >
> > I have this function called at the beginning of the fork:
> > # Redirect stdout and stderr to a file and flush the buffers on a write
> > def redirect_all_output_to_file file
> > log = File.new(file, "w+")
> > STDOUT.reopen log; STDERR.reopen log
> > STDOUT.sync = true
> > end
> >
> > When I add Process.setsid to the end of that function, when I
> > background the ruby process, stuff keeps writing to the log file, but
> > my controlling terminal gets all messed up. The only keys on my
> > keyboard that work are 'e', 's', the space bar, and the backspace key,
> > and they only work half the time. The terminal works normally once
> > the ruby process is killed.
>
> Ah, this appears to be an rsh issue, not a Ruby one. (can't use ssh
> here because people are too lazy to set up ssh keys or something)
>
> $ rsh machine some_command &
> That seems to need to wait for input, even if some_command doesn't
> read from stdin.
>
> $ ssh machine some_command &
> works as expected.
>
> My workaround is to create a file with half a dozen blank lines and do
> $ rsh machine some_command < file_with_blank_lines &
>
> But that seems icky.
Sorry for all the non-ruby related noise, but the problem is fixed.
From the BUGS section in the rsh man page:
If you are using csh(1) and put a rsh in the background without redirect-
ing its input away from the terminal, it will block even if no reads are
posted by the remote command. If no input is desired you should redirect
the input of rsh to /dev/null using the -n option.
Joe