sending stdin to a shell command in perl

A

Andrew

Hi,
in my simple perl script I have to send string to stdin of an
excutable binary which I run from perl. So I am doing the following:

e.g.

my ($result) = `echo "this will be sent to command" | ./command 2>&1`;
# process result...

is there more elegant way to send to command's stdin without using
echo?

Thanks
Andrei
 
T

Tad McClellan

Andrew said:
in my simple perl script I have to send string to stdin of an
excutable binary which I run from perl.


perldoc perlopentut

perldoc -f open
 
A

Andrew

perldoc perlopentut

perldoc -f open

Hm, I need to execute command from perl pass something to its stdin
and read from stdout. Can you give an example?
Thanks
Andrew
 
D

Darin McBride

Andrew said:
(e-mail address removed) (Tad McClellan) wrote in message


Hm, I need to execute command from perl pass something to its stdin
and read from stdout. Can you give an example?

That becomes a bit more difficult than I think Tad thought.
Admittedly, I missed it, too.

You may want to look at:

perldoc IPC::Open2
 
M

Matthew Braid

Darin said:
Andrew wrote:




That becomes a bit more difficult than I think Tad thought.
Admittedly, I missed it, too.

You may want to look at:

perldoc IPC::Open2

If IPC::Open2 doesn't work for you (or is a bit unstable - I've had
problems a couple of times if I don't control the code of the process
I'm calling) you can do something like this:

1) create a temp file (File::Temp is good - make sure the file is not
automatically removed on exit)
2) fork with open('|-') (look this one up in the docs given above - very
handy)
3) In the child section, reopen STDOUT (and STDERR if you want) to the
temp filehandle, then exec the program you want to run.
4) In the parent program, print to the child's file handle (that you got
with the open call) the input you want to give it, then close the handle.
5) In the parent, seek to the start of the temp file and read in the output
6) Don't forget to clean up the temp file!

There's a lot of error checking you need to do (eg success of the open,
success of the exec, handling SIGPIPE if the child dies while you're
writing to it etc etc) but it will work without blocking problems (well,
so far it has all the time for me :)

This method doesn't really allow for a system where the parent and child
need to chat back and forth, but if that's the case then usually the
program you're calling will be written to expect interaction and
IPC::Open2 should be OK.

MB
 
E

Eric J. Roode

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

1) create a temp file (File::Temp is good - make sure the file is not
automatically removed on exit)
2) fork with open('|-') (look this one up in the docs given above -
very handy)
3) In the child section, reopen STDOUT (and STDERR if you want) to the
temp filehandle, then exec the program you want to run.
4) In the parent program, print to the child's file handle (that you
got with the open call) the input you want to give it, then close the
handle. 5) In the parent, seek to the start of the temp file and read
in the output 6) Don't forget to clean up the temp file!

There's a lot of error checking you need to do (eg success of the
open, success of the exec, handling SIGPIPE if the child dies while
you're writing to it etc etc) but it will work without blocking
problems (well, so far it has all the time for me :)

This method doesn't really allow for a system where the parent and
child need to chat back and forth, but if that's the case then usually
the program you're calling will be written to expect interaction and
IPC::Open2 should be OK.

Is all this really better than the OP's original method of echoing a
string to a command pipeline within backtics? :)

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP8NJB2PeouIeTNHoEQLV8QCaA8d2n/nQJKWIpSBvfYTnRfM5XqwAnAz8
hywvD69iD+MMVH/X6djAgPwP
=fRHB
-----END PGP SIGNATURE-----
 
D

Darin McBride

Eric said:
Is all this really better than the OP's original method of echoing a
string to a command pipeline within backtics? :)

I suppose it depends on your definition of "better". Since the OP
didn't ask for "better" but "more elegant", I believe that IPC::Open2
is that "more elegant". I'm not as big of a fan of redirecting to a
file and reading that file, so I do not believe it to be more elegant.
It reminds me too much of DOS (which did its "piping" by redirecting to
a file and then redirecting from the file) or certain unix shells that
can't handle some complicated piping. (If that unix shells part sounds
vague, it's because it is - I never know when or where this bug will
hit me.)

If you only need to send a single, short line with no shell
metacharacters, then maybe the OP's method is fine. If you have
extensive dynamic content to send, then a pipe is a much better
solution. And IPC::Open2 is "the" answer for then reading from the
same process. Far from the only way (IO::pipe can work, too, as well
as the OP's method and the piping via file method). But my personal
preference for solving the OP's problem in the general case.
 

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,774
Messages
2,569,596
Members
45,144
Latest member
KetoBaseReviews
Top