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.

migrated from serverfault.com Apr 16 '14 at 23:26

This question came from our site for system and network administrators.

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.

  • 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 '14 at 16:05
  • The set -x needs to be the first line of your program.sh. – Chirag Bhatia - chirag64 Apr 16 '14 at 16:34
  • program is a binary, not a script – karepker Apr 16 '14 at 18:34
  • Isn't the entire interaction being shown on the terminal? Also, are those scanf / stdin statements? – Chirag Bhatia - chirag64 Apr 16 '14 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 '14 at 19:15

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.