15

I'm looking for an example of redirecting stdout to a file using Perl. I'm doing a fairly straightforward fork/exec tool, and I want to redirect the child's output to a file instead of the parents stdout.

Is there an equivilant of dup2() I should use? I can't seem to find it

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Mike
  • 58,961
  • 76
  • 175
  • 221
  • 1
    From within Perl or from the commandline? what OS? – lexu May 25 '10 at 18:58
  • 1
    see here: http://stackoverflow.com/questions/655719/how-do-i-unalias-from-perls-stdout – lexu May 25 '10 at 18:59
  • If it's the case that you're just aiming to redirect the output of the program being `exec` ed and nothing the child process does up to this point, then this question isn't necessarily Perl-specific; it's a matter of shell redirection or using whatever facilities are in-built into the program you're forking to run when you call it. e.g. `exec("program > out.txt");`. – cikkle May 25 '10 at 19:55

5 Answers5

33

From perldoc -f open:

open STDOUT, '>', "foo.out"

The docs are your friend...

ivans
  • 1,465
  • 10
  • 13
  • I had read the question in that way that the OP want to redirect the child's STDOUT from the parent process. – U. Windl Mar 08 '21 at 11:40
7

As JS Bangs said, an easy way to redirect output is to use the 'select' statement.
Many thanks to stackoverflow and their users. I hope this is helpful

for example:

print "to console\n"; 
open OUTPUT, '>', "foo.txt" or die "Can't create filehandle: $!";
select OUTPUT; $| = 1;  # make unbuffered
print "to file\n";
print OUTPUT "also to file\n";
print STDOUT "to console\n";
# close current output file
close(OUTPUT);
# reset stdout to be the default file handle
select STDOUT;
print "to console"; 
user261939
  • 141
  • 1
  • 1
  • Unfortunately this works only internally inside perl script. It doesn't redirect output for commands called by system function. – Znik Feb 26 '14 at 12:34
4

The child itself can do select $filehandle to specify that all of its print calls should be directed to a specific filehandle.

The best the parent can do is use system or exec or something of the sort to do shell redirection.

JSBձոգչ
  • 40,684
  • 18
  • 101
  • 169
3
open my $fh, '>', $file;
defined(my $pid = fork) or die "fork: $!";
if (!$pid) {
    open STDOUT, '>&', $fh;

    # do whatever you want
    ...

    exit;
}
waitpid $pid, 0;
print $? == 0 ? "ok\n" : "nok\n";
codeholic
  • 5,680
  • 3
  • 23
  • 43
  • very nice method, but unfortunately it's impossible return any text against number because system exit function limitation. – Znik Feb 26 '14 at 12:32
3

A strictly informational but impractical answer:

Though there's almost certainly a more elegant way of going about this depending on the exact details of what you're trying to do, if you absolutely must have dup2(), its Perl equivalent is present in the POSIX module. However, in this case you're dealing with actual file descriptors and not Perl filehandles, and correspondingly you're restricted to using the other provided functions in the POSIX module, all of which are analogous to what you would be using in C. To some extent, you would be writing C in very un-Perlish Perl.

http://perldoc.perl.org/POSIX.html

cikkle
  • 458
  • 5
  • 12