Skip to content

Interactive mode

lamerman edited this page Feb 20, 2016 · 6 revisions

You may need interactive mode when it is important to react on output of the process being executed immediately. In this mode you can also write to stdin of the process. Let's have a look at the following script that asks you for your name and prints is

#!/usr/bin/env python
import os
import time
from sys import stdin, stdout

print('Enter your name')
stdout.flush()
userinput = stdin.readline()

print('Hello ' + userinput.rstrip(os.linesep))
print('End')

In the source code we have an example of interactive script in the file example/allinone/test_interactive.spy . Let's copy part of it here

result = ip`example/allinone/hello.py
if result.sreadline() == 'Enter your name':
    result.swriteline('Alexander')
else:
    raise RuntimeError('Unexpected output of script')

welcome_text = result.sreadline()

example/allinone/hello.py is executed here in interactive mode and we receive InteractiveResult. To run command in interactive mode user needs to put the i argument before the command. Arguments are described in more details here.

Interactive result

Interactive result has the following fields

stdout a Stream of stdout. You can read lines from stdout with it.

stderr a Stream of stderr

stdin a Stream of stdin. Using it you can write something to processes being executed.

returncode return code of the command executed. When you access returncode it will first wait until the process ends.

sreadline reads a line from internal stdout Stream

swriteline writes a line to internal stdin Stream

Syntactic sugar (Interactive result)

It is possible to iterate over lines of result like this

result = i`ping -c 3 8.8.8.8
for line in result:
    print line.upper()

Stream

Stream is used as an abstraction above stdin/out/err and provides the following functions

sreadline reads a line from the stream. All lines in shellpy are returned without trailing line separator in the end by default.

swriteline writes a line to the stream. The line separator is added to the end of line by default.

By default means that in the future this may be configured somehow.

As you can see there are now only operation on whole lines, so you cannot read only one character. The assumption was that other operations are very rarely needed in practice, but may be in the future this ability will be added. Looking at the code it seems like it is possible to use _file directly from the stream but it was made protected purposely as internal implementation may change and it will be not possible to provide this interface anymore.

The names of sreadline and swriteline are also slightly different from default readline writeline (not to confuse users) because they have different interfaces.

Syntactic sugar (Stream)

It is possible to iterate over lines of the Stream like this

result = i`ping -c 3 8.8.8.8
for line in result.stdout:
    print line.upper()
Clone this wiki locally