sending stdin to a shell command in perl

Discussion in 'Perl Misc' started by Andrew, Nov 24, 2003.

  1. Andrew

    Andrew Guest

    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:


    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

    Andrew, Nov 24, 2003
    1. Advertisements

  2. perldoc perlopentut

    perldoc -f open
    Tad McClellan, Nov 24, 2003
    1. Advertisements

  3. Andrew

    Andrew Guest

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

    Ben Morrow Guest

    perldoc -q both

    Ben Morrow, Nov 24, 2003
  5. 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
    Darin McBride, Nov 24, 2003
  6. 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
    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.

    Matthew Braid, Nov 24, 2003
    Hash: SHA1

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

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

    Version: PGPfreeware 7.0.3 for non-commercial use <>

    -----END PGP SIGNATURE-----
    Eric J. Roode, Nov 25, 2003
  8. 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.
    Darin McBride, Nov 25, 2003
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.