已解决:当线程在python3的终端中写入数据时,如何不中断命令的输入?

问题描述 投票:0回答:1

我正在开发一个客户端/服务器 cli 应用程序,我遇到了 python3 的 input() 函数和多线程的问题。

这里是示例代码:

import threading
import time

def thread_function():
    for i in range(10):
        time.sleep(3)
        print(f"[Thread {i}]")


while True:
    thread = threading.Thread(target=thread_function)
    thread.start()
    command = input("input> ")
    print("Command:",super1)

此代码提示命令并输出它,同时线程正在运行并随机时间(在本例中每 3 秒)在屏幕上显示数据。当我在提示中输入值时,如果线程显示信息,我的输入将被分成两半,如下所示(例如 whoami):

input> who[Thread 0]
ami
Command:whoami

我正在寻找一种方法来获得类似的东西:

intput> who
[Thread 0]
intput> whoami

在此示例中,我将在线程输出之前键入命令的开头,然后在线程输出之后完成它。它还必须支持“删除”键。

线程数据必须是完全交互的,当线程需要显示信息时,必须同时显示在cli控制台中(不能等待输入函数结束)。

我已经尝试使用 sys.stdin 和 readchar,但我没有找到实现此目的的好方法。

如果有人有想法来实现这种事情,我会很乐意讨论它:)

谢谢

尝试使用sys.stdin和readchar,但我没有找到实现此目的的好方法。

使用readchar,跟随字符列表并显示好东西(线程侧)有点复杂,并且它没有处理del键。

使用 sys.stdin 不可能逐个字符获取完整的命令。

编辑:

对于这个项目,我确实需要在主线程运行的同时获取线程的输出(该线程将有 50% 的时间被输入锁定)。如果线程在回车后输出值,我会错过一些数据:/。我可以给你上下文(比例子更好)。我目前正在从事的项目是:https://github.com/Ph3nX-Z/LightC2,我在帖子中暴露的问题位于libs.client.cliclient脚本中,同时在interact_with_agent函数中真实的陈述。在这个函数中,我需要随时获取命令的输出,同时能够键入命令而不会被代理的输出中断:)

编辑:

我终于找到了一个解决方案(没有真正优化,但还可以):

import readchar
from threading import Thread
import threading
import time

global command
command = ""
lock = threading.Lock()

def print_various(printlock):
    global command
    for _ in range(10):
        time.sleep(2)
        with printlock:
            print("\n"+"[Ok From Thread]"+f"\nInput >{command}",end="")

thread1 = Thread(target=print_various,args=[lock])
thread1.start()

while True:
    with lock:
        print("Input >",end="",flush=True)
    command = ""
    while True:
        try:
            char = readchar.readkey()
        except KeyboardInterrupt:
            command = ""

        if char=="\n":
            print("\n"+command,flush=True)
            break

        if command=="exit":
            break

        elif char==readchar.key.BACKSPACE:
            command = command[:-1]
            with lock:
                print("\r",end='\x1b[2K')
                print(f"Input >{command}",end="",flush=True)
            
        else:
            command+=char
            with lock:
                print(char,end="",flush=True)
    if command == "exit":
        break
``

Maybe if i can split the terminal or check if an user is typing smth in the input statement it would help
python multithreading command-line-interface
1个回答
0
投票

以上是在多线程中使用锁定的一个很好的练习。您的实现没有任何问题,并且计算机肯定正在执行其应该执行的操作。

您的解决方案是建立一个锁,然后在正确的位置使用该锁(获取并释放它)。请记住,锁只是代码不同部分之间关于如何使用资源的协议。在这种情况下,资源是“屏幕”,解决方案是确保没有人在没有正确持有锁的情况下使用屏幕。

我试图在不完全放弃的情况下提出建议:)

这有帮助吗?

编辑

哎呀,抱歉。看来您不想阻止输出。

除了(或可能代替)锁定之外,我建议执行以下步骤:

  • 关闭回声
  • 允许用户输入键盘字符,但保留对何时以及如何将它们“回显”给用户的控制...您会等待他们按 Enter 键吗?您是否还会发出一个回车符,然后回显到目前为止的整个字符串(以便他们可以在新行上看到他们的工作并知道他们正在输入什么)?
© www.soinside.com 2019 - 2024. All rights reserved.