首页 > 解决方案 > 用户输入不再调用交互式回调

问题描述

我正在尝试使用shpython 库制作一个交互式示例。

交互式回调文档中汲取灵感,我编写了两个简单的脚本。

# test_example1.py
import sh

def interact(line, stdin):
    if "Hello" in line:
        stdin.put("me\n")
        return True # end
    print(f">> line: {line}")


print("-Start-")
response = sh.example1(_out=interact, _bg=True)
response.wait()
print("-End-")

shell脚本看起来像:

#!/bin/bash
# example1
echo Good Morning, sir.
echo -n Hello, who am I talking to?:
read varname
echo It\'s nice to meet you $varname

但在控制台中,程序不会继续阅读更多行

-Start-
>> line: Good Morning, sir.
(no more chars, so the input is never shown)

挖掘代码,似乎投票选择器永远不会被唤醒 echo -n Hello, who am I talking to?:

删除 `-n' 标志让 '\n' 被写入可以解决问题,但并非如此,因为某些脚本会提示并在同一行中等待响应。

我尝试使用不同的标志组合而没有任何积极的结果。图书馆sh看起来很棒,所以我确定我正在失踪。

谁能帮我写一些互动的例子?

标签: pythoninteractive

解决方案


了解管道的基本方法:

import sh
def interact(**rules):
    buffer = ''
    def process(chunk, stdin, process):
        nonlocal buffer
        buffer += chunk
        for regexp, answer in rules.items():
            if re.search(regexp, buffer):
                stdin.put(answer + '\n')
                buffer=''
    return process

sh.example1(_out=interact(talking='me'), _out_bufsize=0)

可以与不发送以.结尾的行的提示进行交互,例如 pythoninput或 bashread\n

最后使用更紧凑的调用方式:

import sh

def reply(**kwargs):
    kw = dict(_out_bufsize=0)
    rules = {}
    for k, v in kwargs.items():
        if k[0] == '_':
            kw[k] = v
        else:
            rules[k] = v
        kw['_out'] = interact(**rules)
    return kw


def interact(**rules):
    buffer = ''
    def process(chunk, stdin, process):
        nonlocal buffer
        buffer += chunk
        for regexp, answer in rules.items():
            if re.search(regexp, buffer):
                stdin.put(answer + '\n')
                buffer=''

    return process

sh.example1(**reply(talking='me'))

推荐阅读