I am looking to control the flow of execution of a compiled C program X using bash scripting. The program X only produces text output and I want immediately pause execution when a certain string is printed. After this, I want to switch into bash and execute some commands and then return back into completing X. I have done some reading and testing and only expect/bash scripting seems to meet my needs. However, I am having difficulties achieving my goal.
I have tried spawning X within an expect script and then expect "mystring" followed by sending bash script commands but this only resulted in the bash commands being executed after X terminated.
Does anyone know the approach of achieving this? To clarify, I cannot use gdb in this situation.
#!/usr/bin/expect
spawn X
expect "mystring"
send -- "bash command"
I would spawn a shell instead of spawning X directly. Then you can use the shell to send a SIGSTOP to the program to pause it (unless the program has the capacity to pause when you send something directly to it).
A demo
#!/usr/bin/expect -f
spawn bash
send "unset PROMPT_COMMAND; PS1=:\r" ;# I have a fairly tricky bash prompt
expect -re ":$"
# this stands-in for "X": start a shell that sends stuff to stdout
send {sh -c 'n=1; while [ $n -lt 10 ]; do echo $n; sleep 1; let n=n+1; done'}
send "\r"
# when I see "5", send a Ctrl-Z to suspend the sh process
expect 5 {send \x1a}
expect -re ":$"
# now do some stuff
send "echo hello world\r"
expect -re ":$"
send "echo continuing\r"
expect -re ":$"
# and re-commence "X"
send "fg\r"
expect -re ":$"
# and we're done
send "exit\r"
expect eof
and running it:
$ expect intr.exp
spawn bash
unset PROMPT_COMMAND; PS1=:
$ unset PROMPT_COMMAND; PS1=:
:sh -c 'n=1; while [ $n -lt 10 ]; do echo $n; sleep 1; let n=n+1; done'
1
2
3
4
5
^Z
[1]+ Stopped sh -c 'n=1; while [ $n -lt 10 ]; do echo $n; sleep 1; let n=n+1; done'
:echo hello world
hello world
:echo continuing
continuing
:fg
sh -c 'n=1; while [ $n -lt 10 ]; do echo $n; sleep 1; let n=n+1; done'
6
7
8
9
:exit
exit