【问题标题】:How do I read user commands in bash on the fly with python?如何使用 python 即时读取 bash 中的用户命令?
【发布时间】:2017-08-12 12:00:51
【问题描述】:

我正在处理research project 并尝试读取用户正在输入终端的内容,在评估命令时停止执行,然后恢复(或关闭)会话。

我发现这个example in the docs 会打开一个新会话,记录所有内容并将其写入文件。

在削减额外内容后,我最终得到了这个:

import os, pty

shell = os.environ.get('SHELL', 'sh')

with open('typescript', 'w') as script:
    def read(fd):
        data = os.read(fd, 1024)
        # Parse on the hash
        cmd = data.decode()
        before, sep, after = cmd.rpartition("#")
        script.write(after)
        return data

    pty.spawn(shell, read)

这有两个问题,一个是它是反应式的,另一个是它还捕获给定命令的任何输出。

在寻找另一种方式时,我找到了a different question 的答案:

def wait_key():
''' Wait for a key press on the console and return it. '''
result = None
if os.name == 'nt':
    import msvcrt
    result = msvcrt.getch()
else:
    import termios
    fd = sys.stdin.fileno()

    oldterm = termios.tcgetattr(fd)
    newattr = termios.tcgetattr(fd)
    newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
    termios.tcsetattr(fd, termios.TCSANOW, newattr)

    try:
        result = sys.stdin.read(1)
    except IOError:
        pass
    finally:
        termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)

return result

我阅读了 terminos 文档并认为这可能是要走的路,但我不明白如何使其适应 ENTER 键。

编辑:我正在做的是使用机器学习模型评估命令并决定是否允许执行命令,例如阻止某人使用 sudo rm -rf /。这实际上只是一个概念验证和演示。

有没有更好的方法来解决这个问题?

【问题讨论】:

    标签: python bash terminal


    【解决方案1】:

    尽量不主动阻塞主线程是UI设计的一般原则。如果您希望控制台始终打开以供用户交互,您可以在another thread 中异步运行您的代码。

    可以通过锁定或信号量(请参阅 python 线程 api)来实现您想要的暂停功能,您将从主线程锁定以告诉工作线程停止。快速的谷歌搜索表明,在您只想终止程序的情况下实现stoppable threads in python 非常简单。

    【讨论】:

    • 感谢您的回答!我没有考虑过分拆不同的线程。对于这个程序,主要目标是测试我的后端,UI 并不重要。我的主要关注点只是捕获命令ls -al(或任何其他命令)并进行评估。
    • 好的,喜欢subprocess?。您只是将结果吐回终端吗?
    • 您提供的第二个链接的大多数答案只是说使用raw_inputraw_input 只会在您按 Enter 时返回,那么您为什么选择这种其他数据输入方法?
    • 我正在做的是使用机器学习模型评估命令并决定是否允许命令执行,例如阻止某人进入sudo rm -rf /。这实际上只是一个概念验证和演示。
    • 好吧听起来真的很有用。那么为什么你决定不做类似while(input=raw_input("user: ")):#ML codeif itsAllGood:subprocess(input.split())else:#shutItDown
    猜你喜欢
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 2021-07-17
    • 2010-11-25
    相关资源
    最近更新 更多