Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

hello monks, I am in confusion that whether the problem is with my understanding or am doing something wrong or others. So requesting you to go ease with me in this case. The problem is with the following code
$| = 1;
$i = 0;

$SIG{'INT'} = 'handler_of_int';
sub handler_of_int { 
	print STDOUT "got END\n"; 
	print STDERR "signal caught...\n"; 
	
	close(stdout); exit(0); 
}

while (1)  {
	print STDOUT ++$i;
	sleep (1);
}
When i execute this way, and give CTRL+C ( sigint ), it prints the 'got END'.
perl write.pl
123^Cgot END
signal caught...
But when i execute this same program using tee command, the 'got END' is not getting printed either to file or to stdout. ( tee - read from standard input and write to standard output and files )
perl write.pl | tee file
12^Csignal caught...
cat file
12
Whats wrong with this ?!

Replies are listed 'Best First'.
Re: problem with redirection and piping
by Khen1950fx (Canon) on Jan 10, 2010 at 10:34 UTC
    I tried your script using File::Tee by salva. It responded pretty much as BrowserUk said tee would. Here's the code, minus the print statements:
    #!/usr/bin/perl use strict; use warnings; use File::Tee qw(tee); tee('STDOUT', '>>', 'stdout.txt'); $| = 1; my $i = 0; $SIG{'INT'} = 'handler_of_int'; sub handler_of_int { close('STDOUT'); exit(0); } while (1) { print STDOUT ++$i, "\n"; sleep (1); }
Re: problem with redirection and piping
by BrowserUk (Patriarch) on Jan 10, 2010 at 08:23 UTC

    It's because when you execute a piped chain of programs, the last program in the chain will receive the signal.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      You seem to be implying that only the last command receives the signal, but that's not true. We know the Perl script received the signal since we can observe the signal handler sending output to STDERR.

      I presume what is happening is that the signal is sent to both perl and tee, and that tee exits before reading the text sent by perl in response to the signal.

      If you do kill -INT 1234 where 1234 is perl's pid, tee won't receive the signal, so it will log the text perl outputs from the signal handler.

        excellent, you are right. By sending the INT using PID it works as expected. Great, thats why you people were rocking. Thanks a lot and tons...