【发布时间】:2017-07-07 13:40:25
【问题描述】:
我正在尝试为 Telegram 机器人编写程序来控制我的 Raspberry Pi,以便我发送给机器人的每条消息都将被解释为 shell 命令 [1][2]。
Raspberry Pi 是第 2 版 B 型,运行 Arch Linux ARM。该程序是用 Python 3.6.0 编写的,带有 Telepot 模块,并从 Pi 执行。
到目前为止,我一直在使用模块 subprocess 来执行命令,如下所示:
# Execute a shell command (assuming that the message received is «text»)
P = subprocess.Popen(text, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
# Store the output and the error
(output, error) = P.communicate()
# Send a message with the output
if str(output) != "b''":
bot.sendMessage(my_id, output)
# And another message with the error
if str(error) != "b''":
bot.sendMessage(my_id, error)
机器人工作得很好,但问题是我不能像在真正的 shell 中那样执行每个命令。我特别谈论那些绕过 STDOUT 并将其输出直接发送到 tty 的交互式命令(ssh、ftp... 通常提示输入密码并等到用户键入它)。 subprocess 不允许读取或写入 tty。事实上,如果我向我的机器人发送命令 tty,它会回复:not a tty。
此外,一些 shell 命令动态更新其输出或继续运行直到某些事件发生(例如 ping 8.8.8.8 或 grep pattern),我也没有成功重现它们,因为我无法发送 Ctrl+C 或 @987654330 @。请注意,第二个问题是一个不同的问题,因为可以将 ping 的输出重定向到文件(而不能重定向 [sudo] Password for user:);但在这种情况下,我无法将输入发送到 shell。
此外,作为可选功能,如果机器人能够理解管道、重定向和通配符,那将会很有趣。
在我看来,造成这些问题的原因是我无法与 shell 交互。我相信解决所有问题的方法只有一个。
所以问题是,从广义上讲,我怎样才能实现这样一个允许我通过它运行交互式 shell 命令的机器人程序 [3]?
我想要达到的最终结果的一个例子是(以我和机器人之间对话的形式):
我:密码
机器人:/home/user/some/directory
我:sudo chmod 777 file.txt
机器人:[sudo] 用户密码:
我:qwerty
我:ssh 用户@主机
机器人:user@host 的密码:
我:qwerty2
Bot:欢迎主持...
或
我:猫
我:你好
机器人:你好
我:测试
机器人:测试
我:Ctrl+D
附言
我已经尝试过 Python 的 pexpect 模块,但我认为它对我来说不是很好,因为我不期望任何特定的输出;我只想得到贝壳给我的任何东西。 (也许有一种方法可以做我不知道的事情?)
我也尝试过使用 fifo 文件,但它们不起作用,因为它们连接到 STDIN 和 STDOUT,而不是连接到 tty。
[1] 示例:我发送消息pwd,机器人回复/working/directory。
[2] 没错,我可以使用 ssh 或类似的;但是,让我感兴趣的是,机器人将独立于执行请求的机器的操作系统(无论是 Linux、Windows、Android 还是其他任何操作系统)工作,而无需安装其他软件(甚至无需安装 Telegram,因为存在 Telegram 网络) .
[3] 问题也可能是:如何通过脚本直接连接到 tty?如果更容易,该脚本也可以用 bash 或其他语言编写。但我不想偏袒你,我对每一种解决方案都持开放态度。一旦我在变量中输入/输出,发送消息就不是问题了。
【问题讨论】:
-
你显然需要创建一个 tty。搜索
python subprocess tty会产生一些看起来很可能的想法,包括this one。 -
谢谢@larsks。我试图运行该脚本,但它对我不起作用。它无限期地挂起输入,直到我按Ctrl + C。原谅我,但我是个菜鸟。你能简单解释一下如何创建一个 tty 吗?我已经阅读了很多问题,但没有一个有用。
标签: python bash raspberry-pi telegram-bot interactive-shell