-
Notifications
You must be signed in to change notification settings - Fork 63
Interactive mode
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 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
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 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.
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()