in reply to Re^3: Test whether STDOUT is connected to a file
in thread Test whether STDOUT is connected to a file

Try this instead: system(1, "perl.exe myProg.pl >out.txt 2>&1") or system("perl.exe myProg.pl >out.txt 2>&1 &")
Though this would work, it would create an intermediary CMD.EXE process, and this is something I want to avoid. This is related to the issues discussed in waitpid returns -1 for still running child - I didn't mention this to not complicate things further.

I now use the workaround of having the called process check whether it is still connected to a terminal, and if it is, redirect STDOUT. The solution is not really satisfying, because it opens up its own problems, but for the time being it works. I hope to find something better eventually.

-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re^5: Test whether STDOUT is connected to a file
by JavaFan (Canon) on Aug 19, 2010 at 08:30 UTC
    If you want to avoid using cmd.exe, you'll have to do the redirection yourself. You cannot have your cake (make use of the shells redirection capabilities) and eat it (not start a shell).

    You may want to study perlopentut and perlipc.

      From perlport I concluded that system(1,...) would do the redirection, provided that the application does not run on RISC OS (because for the latter, the doc explicitly mentions that redirection is NOT performed).

      Maybe I read too much into this docs, because for Win32, the redirection problem is not mentioned at all. Since the docs said with RISC OS that redirection does not work, I concluded that on those operating systems where the documentation does not mention redirection, it should work, but actually not mentioning it just means "undefined behaviour". Hence I admit that we can not rely on redirection performed automagically in this case. Of course the question is why it had worked often. I think the answer lies in the following sentence from perlport: system ... As an optimization, may not call the command shell specified in $ENV{PERL5SHELL}.. So I guess that (maybe depending on the arguments), sometimes CMD.EXE was called, and redirection performed; but sometimes the sub-process was started immediately, without CMD.EXE, and no redirection was performed.

      However even this explanation doesn't satisfy completely: If indeed no redirection is performed by Perl, the called process should see the arguments ">...", "2>&1" in @ARGV, but they are not present. Something is eating them without doing proper redirection...
      -- 
      Ronald Fischer <ynnor@mm.st>
        However even this explanation doesn't satisfy completely: If indeed no redirection is performed by Perl, the called process should see the arguments ">...", "2>&1" in @ARGV, but they are not present. Something is eating them without doing proper redirection...

        No. Consider

        #!/usr/bin/perl -- unlink 'out.txt'; system 1, $^X, '-MData::Dumper', '-le','print(1);warn(2);print Dumper( +\@ARGV);', '>out.txt 2>&1'; sleep 1; print `cat out.txt`, "\n",'-'x66,"\n"; sleep 1; print `pslist |grep -c cmd`,"\n",'-'x66,"\n"; system 1, 'perl.exe -MData::Dumper -le "print(1);warn(2);print `pslist + |grep -c cmd`, Dumper(\@ARGV)" >out.txt 2>&1'; sleep 1; print `cat out.txt`, "\n",'-'x66,"\n"; __END__ 1 2 at -e line 1. $VAR1 = [ '>out.txt 2>&1' ]; cat: out.txt: No such file or directory ------------------------------------------------------------------ pslist v1.28 - Sysinternals PsList Copyright ¬ 2000-2004 Mark Russinovich Sysinternals 8 ------------------------------------------------------------------ 2 at -e line 1. 1 pslist v1.28 - Sysinternals PsList Copyright ¬ 2000-2004 Mark Russinovich Sysinternals 9 $VAR1 = []; ------------------------------------------------------------------
        After the 2nd system there is one more cmd process, and @ARGV no longer contains out.txt, ie it is the shell that does redirection.

        You can use Proc::Background to launch processes in the background