- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道这个(such as here)上有类似的话题但我的预期设计有点复杂。
我正在设计将在 SSH 窗口中运行的 CLI 脚本。该脚本将在 Ubuntu 14.10 服务器上托管和执行。它旨在在前台主动监控主机交换机上端口和客户端的当前状态。每 30 秒或根据用户定义,它将通过 SNMP 获取数据,然后刷新信息并将其显示到屏幕上。当它等待下一次刷新时,会有一个计时器指示它何时会再次查询设备以获取信息。
我想允许用户随时按下特定的键来更改输出 View 或编辑键变量。 (功能类似于 Unix top
。)例如,按 t
将要求他们输入循环之间所需的秒数。 h
、m
或 i
将切换显示/隐藏某些列。这些将不会暂停计时器或退出循环,因为更改将在下一次刷新时应用。 r
会强制立即刷新并应用更改。 q
或 Ctrl+C
将退出脚本。
主要事件如下所示:
Query loop <-----------------------------
| |
| Process Data
| ^
| |
v Query Data #SNMPBULKWALK
Timer <------------- ^
| | | |
| | Check time remaining |
| | ^ |
| |_______________| |
|___________________________________|
对于按键中断,它会像这样:
Query loop <----------------------
| | ???<---Change variables
| (Continue) ^
V | |
Timer <--------- !!INTERRUPT!!---------> Identify key
| | | ^
| | Check time remaining |
| | ^ |
| |___________| |
|_____________________________|
我在这里有点难过。我被引导相信我可能需要实现线程——我没有这方面的经验——因为 while
循环本身似乎不能满足我们的需要。我也不确定如何将更改注入(inject)包含变量的对象(例如计时器、显示格式的标志),因为我们的循环将不断使用它。
最佳答案
这并不复杂,也不需要任何包。
它唯一的问题是它需要在程序退出时将终端恢复正常。
即如果程序崩溃,终端将无法恢复,用户将看不到他正在输入的内容。
但是如果用户知道他在做什么,他可以强制重启 shell,一切都会恢复正常。
当然,您可以更轻松地使用此代码并使用 raw_input() 来完成这些工作。
from thread import start_new_thread as thread
from time import sleep
# Get only one character from stdin without echoing it to stdout
import termios
import fcntl
import sys
import os
fd = sys.stdin.fileno()
oldterm, oldflags = None, None
def prepareterm ():
"""Turn off echoing"""
global oldterm, oldflags
if oldterm!=None and oldflags!=None: return
oldterm = termios.tcgetattr(fd)
newattr = oldterm[:] # Copy of attributes to change
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
def restoreterm ():
"""Restore terminal to its previous state"""
global oldterm, oldflags
if oldterm==None and oldflags==None: return
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
oldterm, oldflags = None, None
def getchar():
"""Get character from stdin"""
prepareterm()
while 1:
try:
c = sys.stdin.read(1)
break
except IOError:
try: sleep(0.001)
except: restoreterm(); raise KeyboardInterrupt
restoreterm()
return c
def control ():
"""Waits for keypress"""
global running, done
while running:
c = getchar().lower()
print "Keypress:", c
if c=="q": print "Quitting!"; running = 0; break
done += 1
def work ():
"""Does the server-client part"""
global done
while running:
# Do your stuff here!!!
# Just to illustrate:
print "I am protending to work!\nPress Q to kill me!"
sleep(1)
print "I am done!\nExiting . . ."
done += 1
# Just to feel better
import atexit
atexit.register(restoreterm)
# Start the program
running = 1
done = 0
thread(work, ())
thread(control, ())
# Block the program not to close when threads detach from the main one:
while running:
try: sleep(0.2)
except: running = 0
# Wait for both threads to finish:
while done!=2:
try: sleep(0.001)
except: pass # Ignore KeyboardInterrupt
restoreterm() # Just in case!
在实践中,如果不将终端恢复到正常状态,程序应该永远无法退出,但糟糕的事情发生了。
现在,您可以通过仅使用一个线程并将您的工作循环放在主线程中来简化事情,并使用 raw_input 从用户获取命令。或者甚至更好,将您的服务器-客户端代码放在后台并在主线程中等待输入。
使用线程模块而不是原始线程也可能更安全。
如果您使用 asyncore 模块,您将让每个客户端各自运行,并且您的主线程将被 asyncore.loop() 占用。您可以覆盖它,即重写它来检查输入和其他你想做的事情,同时保持 asyncore 检查同步。此外,重负载需要覆盖其中的一些讨厌的函数,因为如果我没记错的话,它的缓冲区固定为 512 字节。否则,它可能是解决您的问题的好方法。
最后,为了清楚起见,没有回应用户输入的代码是从 getpass 模块中获取和改编的。只有一点点是我的。
关于python - 使用 Python,如何在后台等待按键时在前台运行循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31551081/
从 0 开始搭建一套后台管理系统,成本巨大,所以都会选择一套成熟的组件库,基于此,再堆叠业务逻辑。我们公司的组件库基于 Ant Design。Ant Design 包含一套完整的后台解决方案,不仅
在我的 IOS 应用程序中,我有一个标记为 retain 的 NSDate* 属性 当我的应用程序再次激活时,属性值已被释放。 我是否误解了属性和内存管理的工作原理,我该如何防范? 最佳答案 很明显,
我有一个使用 BackgroundWorker 组件的示例 WinForms 应用程序。它工作正常,但是当我点击 Cancel 按钮取消后台线程时,它并没有取消线程。当我点击 Cancel 按钮调用
我目前正在开发一个应用程序,该应用程序在启动时会对服务器执行 ping 操作,该服务器会为每个连接的设备返回一个唯一标识符。设备每 5 秒从服务器检索另一页以获取一组不同的数据。这个唯一的 ID 可以
我正在开发一个应用程序,当它通过主页按钮在后台按下时,计时器应该启动,当应用程序返回前台并且计时器已经过了一定时间时,应该是执行。 我的问题是 当我的应用程序转到背景/前景? 是否有特殊的方法或其他技
我有 map View ,其中几乎没有 MKPointAnnotation。 一切正常,但是, View 的 MKPoiintAnnotation 的“背景”是“不可见的”,因此不是很“可见”。 我想
我在 iOS 中开发广告数据应用程序。我的应用程序广告数据在前台很好。但我想在 ios 后台宣传信标数据。我设置了背景外设设置。和广告数据 advertisingData = [CBAdvertise
如果我有一组操作,我想根据特定条件在后台工作程序中运行,例如,我有 10 个条件 if(a) BackgroundWorker doA = new backgroundworker() if(
我想独立运行一个函数。从我调用的函数中,我想在不等待其他函数结束的情况下返回。 我试过用 threadind,但这会等待,结束。 thread = threading.Thread(target=my
我想在用户在线时立即执行一些任务,即使他在后台也是如此。我正在使用 Reachability 类来检查互联网。但是当我在后台时,这个类没有通知我。我知道有人早些时候问过这个问题,但没有找到任何解决方案
我在后台播放文本转语音时出现间歇性(哎呀!)问题,由 Apple Watch 触发。我已经正确设置了后台模式、AVSession 类别和 WatchKitExtensionRequest 处理程序。
我有一个相当复杂的程序,所以我不会在这里转储整个程序。这是一个简化版本: class Report { private BackgroundWorker worker; public
我有一个任务在 backgroundworker 中运行。单击开始按钮,用户将启动该过程,并获得一个取消按钮来取消处理。 当用户点击取消时,我想显示一个消息框“进程尚未完成,你想继续吗”。 这里我希望
我有一个按以下方式编码的脚本。我想将它作为后台/守护进程运行,但是一旦我启动脚本,如果我关闭它从程序运行的终端窗口终止。我需要做什么来保持程序运行 loop do pid = fork do
我正在制作一个使用 ActivityRecognition API 在后台跟踪用户 Activity 的应用,如果用户在指定时间段(例如 1 小时)内停留在同一个地方,系统就会推送通知告诉用户去散步.
当尝试使用 URLSession 的 dataTaskPublisher 方法发送后台请求时: URLSession(configuration: URLSessionConfiguration.ba
当我编译这段代码时,我得到了他的错误,对象引用设置为null,错误位置在Dowork中,argumenttest.valueone = 8; public partial class Form1 :
有什么方法可以使用最小化或不活动的应用程序吗?我可以打开我的应用程序,然后打开并使用另一个应用程序,然后按一个按钮来激活我的程序吗? 例如,打开我的应用程序,打开 Safari,按下按钮(F1 或任何
我的具体要求是一个在后台运行的应用程序,被通知显示器即将进入休眠状态或者设备已经或即将达到空闲超时 - 然后唤醒并执行一些(简短的)一段代码。 我在这里找到了有关应用程序被置于后台或暂停的通知的引用:
我有一个 LSUIElement 设置为 1 的应用程序。它有一个内置编辑器,因此我希望该应用程序在编辑器打开时出现在 Cmd+Tab 循环中。 -(void)stepIntoForegrou
我是一名优秀的程序员,十分优秀!