1

This is sort of a clunky question as I can't figure out a good way to describe it, but in expect you can do something like this:

interact {
    \001 {do_something}
    \003 {do_something_else}
    "?" {
      set timeout 1
      expect_user {
                   "?" {send "?"}
                   timeout {send_user "show a menu of the things you can do"}
      }
      stty raw -echo
      set timeout 60
    }
    \035 {send "^]"
      send "quit\r"
      send_user "\n"
      exit
    }
  }

which would create an interactive session where the user could go about business as usual, but upon pressing keyboard combos (ctrl+a, ctrl+c, ctrl+e, ?, etc) execute actions or display text describing the possible shortcuts.

I'm trying to update a number of scripts to python & pexpect but haven't been able to figure out if this is possible in pexpect. I tried putzing around with an input filter but it seems this isn't really the 'right' place to do it, or maybe I just can't seem to find any good examples of it in action.

@pynexj: tried your script, though I'm not getting anything on stdout from the ctrl commands.

16:51:16 ~/scripts $ p3 testInputFilter.py | tee testInput.txt
16:51:19 ~/scripts $ ps u
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
usr 45721  0.0  0.0 109620  1876 pts/1    Ss   16:49   0:00 -ksh
usr 46622  0.0  0.0 108436  1776 pts/1    S    16:51   0:00 bash
usr 46734  5.5  0.0 135728  7688 pts/1    S+   16:51   0:00 python3.6 testI
usr 46735  0.0  0.0 100912   632 pts/1    S+   16:51   0:00 tee testInput.t
usr 46736  0.0  0.0 108336  1692 pts/5    Ss   16:51   0:00 /bin/bash --nor
usr 46759  0.0  0.0 110236  1132 pts/5    R+   16:51   0:00 ps u
16:51:21 ~/scripts $ ^C
16:51:42 ~/scripts $ exit
16:51:43 ~/scripts $ cat testInput.txt
16:51:19 ~/scripts $ ps u
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
usr 45721  0.0  0.0 109620  1876 pts/1    Ss   16:49   0:00 -ksh
usr 46622  0.0  0.0 108436  1776 pts/1    S    16:51   0:00 bash
usr 46734  5.5  0.0 135728  7688 pts/1    S+   16:51   0:00 python3.6 testI
usr 46735  0.0  0.0 100912   632 pts/1    S+   16:51   0:00 tee testInput.t
usr 46736  0.0  0.0 108336  1692 pts/5    Ss   16:51   0:00 /bin/bash --nor
usr 46759  0.0  0.0 110236  1132 pts/5    R+   16:51   0:00 ps u
16:51:21 ~/scripts $ ^C
16:51:42 ~/scripts $ exit
16:51:57 ~/scripts $
L Y E S - C H I O U K H
  • 4,765
  • 8
  • 40
  • 57
Chris
  • 119
  • 1
  • 10
  • You might want to show some of your python code, so people can help you fix it. – glenn jackman Mar 01 '18 at 02:58
  • in case u also need to use *output_filter* some day, see [using-expect-and-interact-simultaneously-in-pexpect](https://stackoverflow.com/questions/43371249/) :) – pynexj Mar 02 '18 at 14:04

1 Answers1

2

See following example (works for both Python2 and Python3):

[STEP 114] # cat foo.py
import pexpect

def input_filter(s):
    if s == b'\x03':
        return b'\r: r u going to kill me? press ctrl-d to exit!\r'
    elif s == b'\x04':
        return b'\r: ok, bye; exit\r'
    else:
        return s

proc = pexpect.spawn('bash --norc')
proc.interact(input_filter=input_filter)
proc.expect(pexpect.EOF)
[STEP 115] # python foo.py
bash-4.4# ps                      <-- user input
   PID TTY          TIME CMD
 77616 pts/56   00:00:00 bash
 77617 pts/56   00:00:00 ps
bash-4.4#                         <-- press CTRL-C
bash-4.4# : r u going to kill me? press ctrl-d to exit!
bash-4.4#                         <-- press CTRL-D
bash-4.4# : ok, bye; exit
exit
[STEP 116] #
pynexj
  • 19,215
  • 5
  • 38
  • 56
  • Here's the result when I use this: – Chris Mar 01 '18 at 16:52
  • Thanks, this does work now in Python 3, though the colon operator is a shell specific thing. If I try to print something within that, it doesn't appear until after the EOF occurs. Is there no equivalent to send_user for pexpect? – Chris Mar 02 '18 at 12:20
  • the print statements are only appearing AFTER EOF, not during the interactive session. If per my original question, I wanted to display a menu of ctrl+modifier commands to my user, print would not suffice, and returning a string would merely send that string into the spawned child. – Chris Mar 02 '18 at 13:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/166102/discussion-between-chris-and-pynexj). – Chris Mar 02 '18 at 13:05
  • No problem. Here is a [new question](https://stackoverflow.com/questions/49069887/pexpect-equivalent-of-send-user) posed with the example. – Chris Mar 02 '18 at 13:16