2

I execute an application from a script file and redirect stdin to it from here-doc like this:

my_cli << HERE_DOC
enable
configure
10
exit
exit
HERE_DOC

This works as expected, but I don't see neither the input nor the app output. The application is an interactive prompt written in C. When I interact manually with it, I see the prompt itself and responses to my input, but when I execute the aforementioned script I see nothing. I would like it to print the input and the output as if a real user was typing. Do you know how to achieve that?

3

It seems like there ought to be a better way, but you could use a wrapper function:

wrapper () { local text=$(</dev/stdin); echo "$text"; my_cli <<<"$text"; }
wrapper << HERE_DOC
enable
configure
10
exit
exit
HERE_DOC

To process the here doc line by line:

wrapper2 () { local line; while read -r line; do echo "$line"; my_cli <<<"$line"; done; }

If you manually interact with your program, does it show output? Does it output to stdout or stderr?

Another option that might work for you is expect.

  • As far as I understand, this way I'll see the input text only. Is there a way to see it together with the output of the application. I mean, the application reacts to the input and I'd like to see the input and then the reaction for each step in the correct order. – FireAphis Sep 26 '10 at 16:41
  • @FireAphis: See my edit. Can you tell me what your program is or what it does? Is it a script that you can modify? – Paused until further notice. Sep 26 '10 at 16:57
  • I have updated the question. – FireAphis Sep 27 '10 at 7:38
  • @FireAphis: It's possible that your program is interacting directly with the tty or behaves differently when it doesn't have a tty. As I mentioned in my answer, you should try expect which is made for this purpose and works by setting up a pseudo tty. – Paused until further notice. Sep 27 '10 at 10:57
1

I see Perl!

Well, you can't do it if you're using qx or system calls, since they are blocking in nature (yes, you can do system("program &") or call it from another thread and detach it.

Launcher thread:

threads->create( sub { 
                    threads->self->detach(); 
                    qx"$cmd > file1.cmd";
});

Main code: :

threads->create( sub {
while (1) { 
 get file size, if it is bigger than second ago - read new line, increase size
 parse new line, if any?
 sleep 1;
}
} );

Better, use POE::Wheel::FollowTail

Another solution is to redirect output of each of your programs to named fifo and read them all from your prog, keeping an eye for new lines.

man mkfifo
1
(tee /dev/fd/42 | mycmd) 42>&1 <<EOF
blah
blah
EOF

It won't look exactly like a real user - all input will be printed immediately. expect is probably better for this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.