in reply to Re: How to execute external programs from perl script
in thread How to execute external programs from perl script

It works !

adding to my query, I want to type 3 commands, but not just 1.

Something like this

system 'echo "r"| echo "Y"|echo "r"| phylip sub_program_1';

first command echo "r" works, but not second and third. Any idea why it is not working ?

I would appreciate if you direct me to documentation for this function. I would like to learn basics myself :-)

thanks

Replies are listed 'Best First'.
Re^3: How to execute external programs from perl script
by Anonyrnous Monk (Hermit) on Feb 04, 2011 at 15:02 UTC

    Try

    system 'echo "rYr" | phylip sub_program_1';

    or

    system 'echo -e "r\nY\nr" | phylip sub_program_1';

    The latter would be appropriate in case you have to press Enter after typing the respective letter when you do it interactively.

    The way this works is essentially as follows (somehwat simplified): each program has three standard handles for I/O: stdin, stdout, stderr (we can forget about stderr for the moment).

    When you run a program from the command line "normally" (i.e. without a pipe or redirection) those standard handles are connected to the terminal where your command shell runs in.  What you type on the keyboard is forwarded to the program as input, and what the program outputs is displayed in the terminal.  When you connect two programs via a pipe

    program_A | program_B

    stdout of A is being sent to stdin of program B. The respective handles are also disconnected from the terminal, which means that B no longer gets its input from the keyboard, but from program A (and the output of A is no longer displayed in the terminal).

    In your particular case, program A is the command "echo", which simply sends to stdout whatever you pass it as arguments, which then ends up as input for program B (phylib) as if you had typed it on the keyboard.  In other words, the idea is simply to make echo send to stdout exactly the same characters that you would have typed interactively otherwise.

    Also, program B only reads as many characters as it wants at a time, even if program A has output everything at once. The associated buffering (and blocking of I/O, if needed) is handled behind the scenes by the OS.

      Thanks for explaining

      One more addition if you permit me - How to add delay after each step ? I am thinking something like this-

       system 'echo -e "r"; sleep 2; echo "Y"; sleep 2; echo "r" | phylip sub_program_1';

      I am sure, above code is wrong :( bcoz it is not working !

      I suspect, lack of delay is causing "phylip" to abort after first command.

      Out of context remark - This conversation appears to be like happening face to face... and I am liking it :-)

        There should be no need to add delays in between outputting the characters.  As I tried to explain, the OS takes care of storing echo's output until it has been read. It shouldn't matter if the consuming side takes a while to get done; the OS will happily keep the data in the fridge...

        If you still wanted to do what you were trying above, you'd need to add a pair of parentheses around the echos and sleeps (aka subshell), so the collective output would be piped into phylib.  As you have it, only the last echo "r" would be piped.

        Compare the following  (I replaced your phylib with a bit of Perl code that also reads 3 chars):

        $ echo abc | perl -e'for (1..3) {print "Q$_ -> "; read STDIN,$r,1; pri +nt "$r\n"; sleep 2}' Q1 -> a Q2 -> b Q3 -> c

        Here, the reading side is slow, but as you can see, every answer still ends up where expected.

        The net effect of putting the delays on the other side (in between the echos), will superficially behave the same, but the difference is that the reading end will now have to wait until data becomes available:

        $ (echo -n a; sleep 2; echo -n b; sleep 2; echo -n c) | perl -e'for (1 +..3) {print "Q$_ -> "; read STDIN,$r,1; print "$r\n";}' Q1 -> a Q2 -> b Q3 -> c

        I.e., in both cases, there will be 2 sec intervals between outputting Q/A's.

        As for phylib aborting after the first input... are you sure it reads char-by-char, or does it maybe read lines (i.e. characters up until a newline)? In the latter case, you'd need to have echo output \n in between characters, or else the entire "rYr" would be consumed by the first read...

        P.S.: echo -e interpolates escapes (like "\n"), and echo -n suppresses outputting of a trailing newline (which you don't want in case the program is reading char-by-char).   (Update: at least that's what the bash builtin echo, and /bin/echo on Linux does — unfortunately, different versions of echo are notoriously known for their incompatibilities wrt behavior and options...)