LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Perl stderr&stdout redirect question (https://www.linuxquestions.org/questions/programming-9/perl-stderr-and-stdout-redirect-question-714368/)

Fredde87 03-25-2009 11:16 AM

Perl stderr&stdout redirect question
 
Hi,

I am trying to do the following in a perl script,

my $disk="hdc";
system("dd if=/dev/sdb of=/dev/${disk} &> /tmp/${disk}.txt &");

Basically I want to start a dd, output stdout and stderr to a file and fork it.

I have another bash script which does a "kill -USR1 `pidof dd`" in the background which runs once a second. Sending USR1 as you might know causes dd to send the current status out to stderr.

It all works apart from that the file /tmp/hdc.txt becomes blank if I run it form within perl. If I just type "dd if=/dev/sdb of=/dev/hdc &> /tmp/hdc.txt &" in a bash prompt then it does work exactly as I want it to.

Why is this? What am I doing wrong? I can only assume that it is perl who steals all the stdout and wont let me redirect it to a file?


Thanks!

Sergei Steshenko 03-25-2009 11:30 AM

/bin/sh redirection of both stdout and stderr is:

Code:

program 1>screen.log 2>&1
And that's what you need.

Fredde87 03-25-2009 11:39 AM

Quote:

Originally Posted by Sergei Steshenko (Post 3487440)
/bin/sh redirection of both stdout and stderr is:

Code:

program 1>screen.log 2>&1
And that's what you need.

Thank you, I tried this but still the same problem. It did however work in the shell, but not in Perl.

Fredde87 03-25-2009 11:51 AM

Quote:

Originally Posted by Fredde87 (Post 3487447)
Thank you, I tried this but still the same problem. It did however work in the shell, but not in Perl.

Okay ignore everything in this thread. The reason doesnt seem to be due to Perl. I should have mentioned that this script is a CGI script. If I run the script in a shell it does actually work as well.

I am trying to run the script on a lighttpd server which is running as root (I know, bad but it is a internal network server which is just going to be used to mirror hard drives).

I can see dd in the process list so it does appear to start and the hard disk activity light is flashing so it appears to be copying fine as well. It is just that I cant seem to grab the stderr. What could be causing this?

David1357 03-25-2009 01:23 PM

Quote:

Originally Posted by Fredde87 (Post 3487451)
What could be causing this?

Try this
Code:

my $disk="hdc";
system("dd if=/dev/sdb of=/dev/${disk} > /tmp/${disk}.txt 2>&1 &");

The first ">" tells the shell to redirect stdout to the file. The final "2>&1" tells the shell to redirect stderr to stdout. That has to be last. I forget why.

This webpage has some interesting information on the importance of the order of redirection.

Anyway, it worked here for this example:
Code:

#!/usr/bin/perl -w
my $disk="hdc";
system("dd if=/dev/zero of=${disk}.bin > ${disk}.txt 2>&1 &");


Fredde87 03-26-2009 04:43 AM

Quote:

Originally Posted by David1357 (Post 3487532)
Try this
Code:

my $disk="hdc";
system("dd if=/dev/sdb of=/dev/${disk} > /tmp/${disk}.txt 2>&1 &");

The first ">" tells the shell to redirect stdout to the file. The final "2>&1" tells the shell to redirect stderr to stdout. That has to be last. I forget why.

This webpage has some interesting information on the importance of the order of redirection.

Anyway, it worked here for this example:
Code:

#!/usr/bin/perl -w
my $disk="hdc";
system("dd if=/dev/zero of=${disk}.bin > ${disk}.txt 2>&1 &");


Sorry, that didnt work either. But I dont think the redirect is the problem anymore. After some googling I have found out that most webservers wont allow stderr to be redirected. It seems that they will take any stderr output and put it to their error.log file.

This seems to be the case as I can see a lot of stderr output in it. However not the one I am trying to redirect.

I have read a bit about people suggesting to use Tie::STDERR or CGI::Carp but I am unsure how to do this.


All times are GMT -5. The time now is 12:12 AM.