commands, which is better

R

Robert Wallace

i'm trying to run a system command like ls,dir,ping,uptime, etc...

I tried the following two methods. both works. both produce the same
output.
is there a difference? is there a situation where I would use one over
the other?
I guess the open allows me to do more on-the-fly stuff.
what else?



# this one ##########################################################
open (SYS, "/temp/uptime.exe |");
while($the_sys = <SYS>){
$the_sys =~ s/\015\012/<br>\015\012/g;
print $the_sys . "<br>\n";
}
close (SYS);


# and this one
##########################################################
$sys=`/temp/uptime.exe`;
$sys=~s/\015\012/<br>\015\012/g;
print $sys;
 
A

Anand

second one will fork new process as you are using *NIX thing. If you do
not want to create new process (which will take some or more system
resources) you are better off using PURE perl as in case of first example.

--Anand
 
E

Ernst-Udo Wallenborn

Robert Wallace said:
is there a difference? is there a situation where I would use one over
the other? [snip]
# this one ##########################################################
open (SYS, "/temp/uptime.exe |"); [snip]
# and this one
$sys=`/temp/uptime.exe`;


On *NIX, both commands do almost the same. Both fork a child and both execute
the command in a subshell. The first method reads the output of uptime.exe
line-by-line, which allows you to close the handle as soon as you read the
data you're interested in. If tha output of uptime.exe was very long, this
difference would matter.

You probably want to read the perlipc manpage.
 
T

Tad McClellan

[ top-posting corrected. ]


Anand said:
Robert Wallace wrote:

second one will fork new process as you are using *NIX thing.


So will the first one.

Neither of them does the "*NIX thing".

Nearly every OS needs a process to run a program in.
 
M

Mina Naguib

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1


[Please do NOT top-post]
Anand said:
second one will fork new process as you are using *NIX thing. If you do
not want to create new process (which will take some or more system
resources) you are better off using PURE perl as in case of first example.

--Anand

That's not correct. The first example also forks a second process.

The only difference is in the first example you're reading the output yourself line-by-line, while
with the second example perl does that job for you and returns the whole output in one chunk.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQE/lW/eeS99pGMif6wRAph4AJ9vkInKaXZZ/y9385wblxpAqYgj1wCeIDVI
Sxfis+WkDK9psa5bc1yuYmU=
=wcX4
-----END PGP SIGNATURE-----
 
T

Tedd Hansen

Using the first one, Perl receives data directly and you process it line by
line.
Using the second method will give the OS (and Perl) a chance to buffer data
and write chunks to your variable.

The first example;
+ You can analyze data as it arrives
+ You can terminate the application at any time using close()
- Using the usual "while <>" eats much CPU, so not so good when receiving
big amounts of data that isn't meant for line-by-linbe processing (my
theory)
+ You can use (binmode() and) sysread() to simulate the second example
+ Lets you pipe data TO the command (| command)

The second example;
- Your application blocks until the command you are running terminates (can
be bypassed by alarm())
- You can't terminate the command you are running (unless you trace it's
PID)
- You must write your own process-line-by-line-code if required
- If the command returns loads of data, it eats up memory
+ Takes up less CPU in some cases where you don't want to process the
feedback line by line (my theory)

Also consider the more secure (in form of argument parsing):
system($cmd, $param1, $param2, @params)
and related
exec()
open(FH, "|-") (fork perl with a filehandle piped to STDINPUT and STDOUTPUT
of the child)


Remember when executing commands that a fork is actually a fork followed by
a complete overwrite of the program's code. This means that on operating
systems where Perl has problems with forking and signaling you need to
consider this. There are some simple workarounds, the most famous;

sub REAPER {
$waitedpid = wait;
}

$SIG{CHLD} = \&REAPER;
# Now execute commands or fork or something
 
R

Robert Wallace

Tedd said:
Using the first one, Perl receives data directly and you process it line by
line.
Using the second method will give the OS (and Perl) a chance to buffer data
and write chunks to your variable.
......


whoa
thanks for the analysis folks
looks like i've got a load of research ahead of me.
 
G

Greg Miller

# this one ##########################################################
open (SYS, "/temp/uptime.exe |");
while($the_sys = <SYS>){
$the_sys =~ s/\015\012/<br>\015\012/g;
print $the_sys . "<br>\n";
}
close (SYS);


# and this one
##########################################################
$sys=`/temp/uptime.exe`;
$sys=~s/\015\012/<br>\015\012/g;
print $sys;

In addition to what they others said: in the first example,
if the output of the uptime.exe program pauses long enough for the
perl program to catch up, the while loop will terminate even if the
program outputs more data later. IIRC

Greg Miller (e-mail address removed) http://www.gregmiller.net
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top