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

Ive got a problem with an existing script that makes a system() call, and redirects to a file, like this
system("somecmd -args >outfile");

this works fine, but now I need the script to read a filename from <STDIN>, so I tried doing somethng like this:

$filename = <STDIN>;
...which also works fine.

The problem is that now that I started using/making references to <STDIN>, it seems to have broken the redirection within the system() call.
Now, output that *should* be going to ">outfile" is actually being printed/redirected to the screen. So, somehow by simply accessing/touching <STDIN>, it threw off STDOUT for the entire script, including STDOUT for any system() calls.

I dont have permission to make changes to the system() calls, I can only change the the way that I read from STDIN...
So, how can I avoid this issue with "breaking" STDOUT for the system calls while still being able to read from STDIN??? please help...
  • Comment on problem with system(), stdin, and stdout

Replies are listed 'Best First'.
Re: problem with system(), stdin, and stdout
by graff (Chancellor) on Sep 30, 2008 at 01:28 UTC
    Usually, if you are reading from STDIN, there's a line feed at the end of each input. If you don't chomp that before putting it into a command line for your "system" call, your sub-shell will get a line break at the end of the string that you've read from stdin, which will be before the angle-bracket redirection, and this means that redirection won't work as intended in the sub-shell.

    Chomp your strings from stdin before using them in "system()" calls.

Re: problem with system(), stdin, and stdout
by ikegami (Patriarch) on Sep 29, 2008 at 20:57 UTC

    Now, output that *should* be going to ">outfile" is actually being printed/redirected to the screen.

    Could you give us a short a short runnable program that demonstrates this?

    And are you sure the child is writing to its STDOUT and not its STDERR? Try

    system("somecmd -args >outfile 2>&1");
Re: problem with system(), stdin, and stdout
by JavaFan (Canon) on Sep 29, 2008 at 20:57 UTC
    That doesn't make much sense. 'somecmd' is a different command, and has its own stdin/stdout (and it's the shell that will do the redirection, not perl). Besides, just reading from stdin doesn't modify stdout.

    Could you show us a small self contained program that shows this problem?

Re: problem with system(), stdin, and stdout
by Animator (Hermit) on Sep 29, 2008 at 21:15 UTC
    Does your code contain close STDIN;? If yes, does it also contain: open STDIN, "<", "/dev/null";?
      Nevermind...stupid yet subtle mistake...
      I wasnt chomping the result from STDIN...
      should have done this:
      chomp($filename=<STDIN>);

      this removes the newline character which kept getting inserted into $filename, giving $filename a value such as '/path/file\n', and thus passing the newline into my $cmd string, making $cmd look like this:

      $cmd = "mycmd -args $filename >outfile"
      ...gives...
      "mycmd -args /path/file\n >outfile"

      So, everytime I passed $cmd to system(), it would execute the cmd and stop at the newline character embedded within $filename, thus skipping the ">outfile" redirection...

      problem solved, but thanks to everyone for pointing out that this apparently should have worked.
      Please add this to your vast collection of mental "gotchas" that can stump users...