2

A typical interaction for a program I've written might look like this:

Enter command: a_command
Completed a command

Enter command: another_command
Completed another command

I typically run my program like ./program < input.txt, where input.txt would contain:

a_command
another_command

I want to be able to capture the entire interaction (not just the output) like above. How can I do this with bash?

EDIT: program is a binary (specifically, it's in C++), not a bash script. I have access to the source code, but I'd like to do this without having to modify the source code.

0

2 Answers 2

0

In order to print the input after the corresponding prompt, you need to know when the program is waiting for input. There's no way to tell from observing the running program: you can't distinguish a program that's waiting for input on stdin from a program that's waiting for something else (network, disk, computation, …).

So the process to obtain a transcript which would look like interactive use has to go like this:

  • Launch the program.
  • Wait for — and recognize — the first prompt.
  • Display and send the input to the first prompt.
  • Ditto with the second prompt for input and all subsequent ones.
  • Quit when the program exits.

The de facto standard tool to script this is Expect. The script would look something like this (warning: not working code, typed directly in my browser):

#!/usr/bin/expect -f
set transcript_file [open "transcript" wb]
spawn myprogram
expect "Enter command:"
puts -nonewline $transcript_file $expect_out(buffer)
send "a_command\r"
puts -nonewline $transcript_file "a_command\r"
puts -nonewline $transcript_file $expect_out(buffer)
send "another_command\r"
puts -nonewline $transcript_file "another_command\r"
puts -nonewline $transcript_file $expect_out(buffer)
…
expect eof
close $transcript_file
0

Add the line set -x in your program file.

Example:

#!/bin/bash
set -x #echo on

ls $PWD

This expands all variables and prints the full commands before output of the command.

output:

+ ls /home/user/
file1.txt file2.txt

Check this answer from Stackoverflow for more similar flags for the set command.

6
  • 1
    This does not work. When I run my program as I specified in the question with redirected input, ./program < input.txt, only ./program is printed. I still do not see the contents of input.txt with the output.
    – karepker
    Apr 16, 2014 at 16:05
  • The set -x needs to be the first line of your program.sh. Apr 16, 2014 at 16:34
  • program is a binary, not a script
    – karepker
    Apr 16, 2014 at 18:34
  • Isn't the entire interaction being shown on the terminal? Also, are those scanf / stdin statements? Apr 16, 2014 at 18:38
  • the output is shown on the terminal, but when I redirect input with <, the input is just fed into the program and not shown.
    – karepker
    Apr 16, 2014 at 19:15

You must log in to answer this question.

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