我正在尝试为Telegram机器人编写程序来控制我的Raspberry Pi,这样我发送机器人的每条消息都应被解释为shell命令[1] [2]。
Raspberry Pi是版本2型号B并运行Arch Linux ARM。该程序使用模块 Telepot 在Python 3.6.0中编写,并从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
),并且我也没有成功重现它们,因为我无法发送{{ 1}}或Ctrl+C
。请注意,第二个是另一个问题,因为可以将ping的输出重定向到文件(虽然无法重定向Ctrl+D
);但在这种情况下,我无法向shell发送输入
另外,作为一个选项,如果机器人能够理解管道,重定向和通配,那将会很有趣
在我看来,适应这些问题的是我无法与shell进行交互这一事实。我相信所有这些解决方案只有一个。
所以问题是,从广义上讲,我如何实现这样一个允许我通过它运行交互式shell命令的机器人程序[3]?
我想要实现的最终结果的一个例子是(以我和机器人之间的对话形式):
我:pwd
Bot:/ home / user / some / directory
我:sudo chmod 777 file.txt
Bot:用户的[sudo]密码:
我:qwerty
我:ssh user @ host
Bot:user @ host的密码:
我:qwerty2
Bot:欢迎主持人......
或
我:猫
我:你好
Bot:你好
我:测试
Bot:test
我:Ctrl + D
P.S。
我已经尝试过用于Python的 pexpect 模块,但我认为它对我不太好,因为我不期望任何特定的输出;我只想得到shell给我的任何东西。 (或许有一种方法可以做我想要的,我不知道的?)
我也尝试过使用fifo文件,但它们不能正常工作,因为它们连接到STDIN和STDOUT,而不是tty。
[1]示例:我发送消息[sudo] Password for user:
,机器人回复pwd
[2]是的,我可以使用ssh或类似的;然而,令我感到兴趣的是,机器人可以独立于执行请求的机器的操作系统工作,无论是Linux,Windows,Android还是其他任何东西,无需安装额外的软件(甚至没有安装Telegram,因为存在Telegram web) 。
[3]问题也可能是:如何通过脚本直接连接到tty?如果更容易,脚本也可以用bash或其他语言编写。但我不想偏向你,我对所有解决方案持开放态度。一旦我在变量中输入/输出,发送消息就不是问题。
答案 0 :(得分:1)
如果我回答我自己的问题,请原谅我,但我确切地找到了我想要的东西,并且我想与你分享。
https://jmendeth.com/blog/telegram-shell-bot/
在上面的链接中,您可以找到安装和使用'shell bot'的说明;从那里你也可以访问github上的源代码。
虽然不是用Python编写的,但是在node.js中,对我来说似乎很完美。它可以即时更新消息,也可以执行图形命令。
P.S。你甚至可以通过机器人运行vim!