How to implement a stdin, stdout wrapper?
Asked Answered
A

4

7

I have an interactive program that runs stdin and stdout. I need to create wrapper that will send X to it's stdin, check that it prints Y and then redirects wrapper's stdin and stdout to program's stdin and stdout just like program would be executed directly.

How to implement this ? X and Y can be hardcoded. Bash? Python?

Edit: I can't run the program twice. It has to be one instance. Here is the pseudocode:

def wrap(cmd, in, expected_out):
  p = exec(cmd)
  p.writeToStdin(in)
  out = p.readBytes (expected_out.size())
  if (out != expected_out) return fail;
  # if the above 4 lines would be absent or (in == "" and out == "")
  # then this wrapper would be exactly like direct execution of cmd
  connectpipe (p.stdout, stdout)
  connectpipe (stdin, p.stdin)
  p.continueExecution() 
Ashbaugh answered 11/12, 2009 at 20:52 Comment(1)
Oh, wow, I was looking along the lines of this question just months ago. (Scripting Cisco devices limited to Telnet sessions...) Wanted to have a script to login (& possibly wipe) a router, and then drop the console to me. +1 to you.Prayerful
P
4

Expect is made for automating the running of other programs - essentially you write something like, in plain text,

Start this program. When it prints out the word "username", send it my username. When it sends "password", send it my password.

It's really great for driving other programs.

Pimp answered 11/12, 2009 at 21:0 Comment(1)
Can it (after executing some commands) give control to stdin/stdout ?Riegel
D
1

Assuming X and Y are files, and that you can invoke the program more than once:

#!/bin/bash

test "`program <X`" = "`cat Y`" && program

Or, to fail more verbosely:

#!/bin/bash

if [[ `program <X` != `cat Y` ]]; then
    echo -e "Assertion that input X produces Y failed, exiting."
    exit 1
fi

program

If you only invoke the program once, Expect is a much simpler alternative than reassigning standard file I/O on the fly.

Devoted answered 11/12, 2009 at 20:56 Comment(2)
This is wrong solution as the second instance of the program will not have the state of the first program.Riegel
@Łukasz, would you please edit your question to add this requirement?Devoted
N
0

You can overwrite the sys module's stdin and stdout

import sys
sys.stdin, sys.stdout = wrapper.stdin, wrapper.stdout

These need to be file objects opened for reading and writing respectively. The original stdin and stdout are found at

sys.stdin, sys.stdout = sys.__stdin__, sys.__stdout__
Nevlin answered 11/12, 2009 at 21:1 Comment(1)
Wrapper can be written in python, but program can't be modified.Riegel
R
0

I'm a little confused as to what exactly you're trying to achieve; as I understand you wish to:

  1. Start the wrapper program specifying the input X, and expected output Y.
  2. Have the wrapper initiate the target program attaching input X to it's stdin, and verifying that it's output matches Y.
  3. Have the target program return, and after output is verified, rerun it from the same instance of the wrapper program, this time using the wrapper programs stdin and stdout.

If this is the case you want to do this:

  1. Have the wrapper program open pipes for the stdin and stdout of the target program.
  2. Fork, and close the appropriate ends of said pipes.
  3. Have the parent process and verify the output, while the child exec()s and executes thh target program.
  4. Wait for the child process to terminate when it's stdout closes.
  5. Have the wrapper program exec() into the target program.
  6. Now the target program will be executing as normal.

If this is correct, I can provide a ~30 line C program, or ~10 line Python program that achives this.

Runyan answered 12/12, 2009 at 14:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.