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

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.

  • Comment on Re^5: Test whether STDOUT is connected to a file

Replies are listed 'Best First'.
Re^6: Test whether STDOUT is connected to a file
by rovf (Priest) on Aug 19, 2010 at 08:59 UTC
    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

        Indeed, you are right!! Now I can see this too. Thank you also for pointing out Proc::Background!

        -- 
        Ronald Fischer <ynnor@mm.st>