如何使用python动态读取bash中的用户命令?

如何使用python动态读取bash中的用户命令?,python,bash,terminal,Python,Bash,Terminal,我正在处理一个会话,试图读取用户输入到终端的内容,在计算命令时停止执行,然后恢复(或关闭)会话 我发现它可以打开一个新会话,记录所有内容,并将其写入文件 在削减额外开支后,我最终得出以下结论: import os, pty shell = os.environ.get('SHELL', 'sh') with open('typescript', 'w') as script: def read(fd): data = os.read(fd, 1024)

我正在处理一个会话,试图读取用户输入到终端的内容,在计算命令时停止执行,然后恢复(或关闭)会话

我发现它可以打开一个新会话,记录所有内容,并将其写入文件

在削减额外开支后,我最终得出以下结论:

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)
这有两个问题,一个是它是被动的,另一个是它还捕获给定命令的任何输出

在寻找另一种方法时,我找到了以下答案:

我阅读了terminos文档,认为这可能是一种方法,但我不知道如何调整它以适应ENTER键


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


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

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


实现您想要的暂停特性可以通过拥有一个锁或信号量(参见python线程api)来完成,您可以从主线程锁定该锁或信号量,以通知工作线程停止。一个快速的谷歌搜索表明,对于您只想终止程序的情况,它的实现非常简单

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


实现您想要的暂停特性可以通过拥有一个锁或信号量(参见python线程api)来完成,您可以从主线程锁定该锁或信号量,以通知工作线程停止。一个快速的谷歌搜索表明,对于您只想终止程序的情况,它的实现非常简单

谢谢你的回答!我没有考虑过换一条线。对于这个程序,主要目标是测试我的后端,UI并不重要。我主要关注的是捕获命令ls-al(或任何其他命令)并进行评估。您只是将结果吐回终端吗?您提供的第二个链接的大多数答案都是使用
原始输入
raw_input
只有在按enter键时才会返回,那么为什么选择这种其他数据输入方法呢?我所做的是用机器学习模型评估命令,并决定是否允许命令执行,比如阻止某人执行
sudo rm-rf/
。这真的只是一个概念证明和演示。好的,听起来它真的很有用。那么,为什么您决定不做像while(input=raw\u input(“user:”):
这样的事情呢?如果一切都好的话:
子流程(input.split())
其他:
;关闭它
谢谢您的回答!我没有考虑过换一条线。对于这个程序,主要目标是测试我的后端,UI并不重要。我主要关注的是捕获命令ls-al(或任何其他命令)并进行评估。您只是将结果吐回终端吗?您提供的第二个链接的大多数答案都是使用
原始输入
raw_input
只有在按enter键时才会返回,那么为什么选择这种其他数据输入方法呢?我所做的是用机器学习模型评估命令,并决定是否允许命令执行,比如阻止某人执行
sudo rm-rf/
。这真的只是一个概念证明和演示。好的,听起来它真的很有用。那么,如果一切正常,为什么您决定不做像while(input=raw\u input(“user:”):
这样的事情呢:
子流程(input.split())
其他:
关闭它
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