discarding stdout when using 'system(@args)'

J

Justin C

I have:

my @args = ("pdflatex", $fnames->{tex});
system(@args) == 0 or warn "Problem running pdflatex : $?\n";

This dumps a lot to stdout (the user's browser). I've tried the above
with:

my @args = ("pdflatex", $fnames->{tex}, "1>/dev/null 2>&1");

But I still get unwanted output to the browser. If I run the two
versions of the command directly on a Linux command line, the one that
discards stdout works as expected. It's just under perl/cgi that it's
not discarding it.

I've had a look at the FAQ, specifically "How can I capture STDERR from
an external command?", and it suggests the change I implemented above.
Am I missing something? Is there another FAQ I should be reading instead?

Thank you for any help you can give.

Justin.
 
J

Justin C

You should read the documentation for the functions that you use.

The first paragraph of

perldoc -f system

points out what the problem is.

It does? It is possible that I'm not understanding the finer points of
what the document says. Here's what it says on my system:

<quote>
Does exactly the same thing as "exec LIST", except that a fork
is done first, and the parent process waits for the child
process to complete. Note that argument processing varies
depending on the number of arguments. If there is more than
one argument in LIST, or if LIST is an array with more than one
value, starts the program given by the first element of the
list with arguments given by the rest of the list. If there is
only one scalar argument, the argument is checked for shell
metacharacters, and if there are any, the entire argument is
passed to the system's command shell for parsing (this is
"/bin/sh -c" on Unix platforms, but varies on other platforms).
If there are no shell metacharacters in the argument, it is
split into words and passed directly to "execvp", which is more
efficient
</quote>

I've read 'man sh' relating to the -c switch, but the more I read
(perldoc or 'man sh') the more I need to read to understand what is
going on.

The bottom line is, I do not understand what it is with "system(@args)"
that means I'm getting STDOUT even though STDOUT is being re-directed.

If you want to use shell redirection, then you must use the
form of system that calls a shell:

system "pdflatex $fnames->{tex} 1>/dev/null 2>&1";

Reading the documentation for system, again, I don't understand how this
differs from what I have. "The argument processing varies depending on
the number of arguments", OK, "starts the program given by the first
element of the list with arguments given by the rest of the list". How
does this differ from your form ("system "pdflatex...") above?

I'm not trying to be difficult here, I just don't get it. Thank you for
taking the time to reply.

Justin.
 
U

Uri Guttman

JC> It does? It is possible that I'm not understanding the finer points of
JC> what the document says. Here's what it says on my system:

JC> <quote>
JC> Does exactly the same thing as "exec LIST", except that a fork
JC> is done first, and the parent process waits for the child
JC> process to complete. Note that argument processing varies
JC> depending on the number of arguments. If there is more than
JC> one argument in LIST, or if LIST is an array with more than one
JC> value, starts the program given by the first element of the
JC> list with arguments given by the rest of the list. If there is
JC> only one scalar argument, the argument is checked for shell
JC> metacharacters, and if there are any, the entire argument is
JC> passed to the system's command shell for parsing (this is
JC> "/bin/sh -c" on Unix platforms, but varies on other platforms).
JC> If there are no shell metacharacters in the argument, it is
JC> split into words and passed directly to "execvp", which is more
JC> efficient
JC> </quote>

JC> I've read 'man sh' relating to the -c switch, but the more I read
JC> (perldoc or 'man sh') the more I need to read to understand what is
JC> going on.

JC> The bottom line is, I do not understand what it is with "system(@args)"
JC> that means I'm getting STDOUT even though STDOUT is being re-directed.

but you are not redirecting stdout. the > syntax is only understood by
the shell and not by perl or exec. when you pass a list of args to
system (or exec) it BYPASSES the shell and does the fork/exec itself
passing in all the args to the new process. try printing out @ARGV when
you do your form of system (run a trivial perl script in system to do
that). so either you use the single string arg form of system and that
will let the shell parse the command and handle redirection or you run
the process yourself with ipc::run or some other method and handle
stdout yourself. you can also run the command in backticks and grab the
stdout yourself which is the same as redirection if you write that
output to where you want it.

JC> Reading the documentation for system, again, I don't understand how this
JC> differs from what I have. "The argument processing varies depending on
JC> the number of arguments", OK, "starts the program given by the first
JC> element of the list with arguments given by the rest of the list". How
JC> does this differ from your form ("system "pdflatex...") above?

one arg vs many args. simple.

uri
 
J

Justin C

system has "more than one argument in LIST" so it executes pdflatex
*directly*, so there is no shell.

Bingo! That's it. I knew it could be explained to me in simple terms!
There is *no* shell.

I'll now go and re-read the thread with a bit more understanding.

Reminds me of The Matrix:

Spoon boy: Do not try and bend the spoon. That's impossible. Instead...
only try to realize the truth.
Neo: What truth?
Spoon boy: There is no spoon.
Neo: There is no spoon?
Spoon boy: Then you'll see, that it is not the spoon that bends, it is
only yourself.

Thank you Tad and Uri, and others who tried earlier in the thread. Your
persistence is appreciated.

Justin.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top