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

something for the stdin of program
some more stuff
  • There's a similar question here Commented Apr 17, 2015 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. Commented Apr 21, 2015 at 21:44

3 Answers 3


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.


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
    Commented Apr 17, 2015 at 7:59

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]!=[]):
  return retVal

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

    print('before sleep1')
    print('before readAllSoFar')
    output = readAllSoFar(p)
    print('got output' + output)

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .