2

What I want though is to run a program and log both the stdin and stdout, but I want the stdin to be supplied from a file.

I thought script log.txt < input.txt would work, but it does not, because the stdin does not get logged, only the output gets logged.

Where input.txt is

./program
something for the stdin of program
some more stuff
  • There's a similar question here – don_crissti Apr 17 '15 at 10:35
  • 1
    There is a problem with interleaving log of stdin and stdout: Input and output can happen concurrently, or even physically in parallel on a multiprocessor machine. That means that there is no defined order for the characters in both streams combined. So the log is merged in a somewhat random way (except there is coordination). In many cases, output is buffered by line, which makes the interleaving line by line - mostly working fine. But it happens that there are random effects, which are hard to understand when buffering is involved. – Volker Siegel Apr 21 '15 at 21:44
0

You already have the stdin log: that's your file.

Otherwise (not sure if this is what you're trying to accomplish), if you rather want a log containing both the stdin and stdout interspersed, you could modify your program to send the lines from stdin to stdout as they're read, before they are processed.

  • I want the log to be interleaved into a single file, like the script command does. What if I cannot modify the program? – Buge Apr 17 '15 at 7:59
0

This is probably not the prettiest solution, but you can do something like:

cat file.txt | tee -a stdin.txt | ./program | tee -a stdout.txt

You could use the same file in both tees, but your input and output might get mangled and unreadable.

0

I ended up hacking this thing together:

import subprocess
import time
import sys

log = open(sys.argv[3], 'w')

input = open(sys.argv[2], 'r')

p = subprocess.Popen([sys.argv[1]], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

def readAllSoFar(proc, retVal=''):
  while (subprocess.select.select([proc.stdout],[],[],0)[0]!=[]):
    retVal+=proc.stdout.read(1)
  return retVal

while True:
    print('starting loop')
    line = input.readline()
    print('read line ' + line)
    if not line:
        print('breaking')
        break

    print('before sleep1')
    time.sleep(0.1)
    print('before readAllSoFar')
    output = readAllSoFar(p)
    print('got output' + output)
    log.write(output)
    time.sleep(0.1)
    log.write(line)
    p.stdin.write(line)

Run it with python runner.py ./program_to_run input.txt output.txt

It assumes any output from a command will be done in a tenth of a second.

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.