gpt4 book ai didi

python - 如何使用 Python cmd shell 捕获 ctrl+c

转载 作者:行者123 更新时间:2023-12-01 07:34:27 41 4
gpt4 key购买 nike

我正在尝试使用 cmd 包在 Python 中创建一个 shell。我想重现“真实”shell(bash,csh,...)的行为,也就是说,当您键入命令并且意识到自己所做的事情是错误的时,您可以执行 ctrl+c 来获得一个新的干净提示。

我 try catch SIGINT,然后调用一个仅返回的方法,但它什么也没做。

这是一个示例:

#! /usr/bin/python
# -*- coding: utf-8 -*-

from cmd import Cmd
import signal
import sys


class myPrompt(Cmd):

def do_exit(self, inp):
"""
Exit the shell
"""
return True

def do_test(self):
print "hello"
return


p=myPrompt()

def signal_handler(sig, frame):
print "world"
p.do_test()
return

signal.signal(signal.SIGINT, signal_handler)

p.cmdloop()


编辑:

我按照 Peter Wood 的建议更改了我的代码:

#! /usr/bin/python
# -*- coding: utf-8 -*-

from cmd import Cmd
import signal
import sys


class myPrompt(Cmd):

def do_exit(self, inp):
"""
Exit the shell
"""
return True


def onecmd(self, line):
try:
return super().onecmd(line)
except:
return False

p=myPrompt()
p.cmdloop()

我收到此错误:

(Cmd) Traceback (most recent call last):
File "./test2.py", line 41, in <module>
p.cmdloop()
File "/usr/lib/python2.7/cmd.py", line 130, in cmdloop
line = raw_input(self.prompt)
KeyboardInterrupt

最佳答案

我已经写了你想要的工作版本。您应该覆盖 Cmd 类的 cmdlooponecmd 方法。

我在 cmdloop 方法中为 KeyboardInterrupt 处理定义了一个新关键字:

if self.use_rawinput:
try:
line = input(self.prompt)
except EOFError:
line = "EOF"
except KeyboardInterrupt:
line = "ctrl_c" # You can handle the `KeyboardInterrupt` exception through this keyword.

我已经在 onecmd 方法中处理了这个关键字。如果 line 变量包含此关键字,该方法会将 \n 写入 STDOUT 并返回。

if line == "EOF":
self.lastcmd = ""
if line == "ctrl_c": # You can handle the `KeyboardInterrupt` exception in this `if` branch.
self.stdout.write("\n")
return

您可以在下面看到完整的代码工作代码:

#! /usr/bin/python
# -*- coding: utf-8 -*-

from cmd import Cmd


class MyPrompt(Cmd):

@staticmethod
def do_exit(*args):
return True

def cmdloop(self, intro=None):
"""Repeatedly issue a prompt, accept input, parse an initial prefix
off the received input, and dispatch to action methods, passing them
the remainder of the line as argument.

"""

self.preloop()
if self.use_rawinput and self.completekey:
try:
import readline

self.old_completer = readline.get_completer()
readline.set_completer(self.complete)
readline.parse_and_bind(self.completekey + ": complete")
except ImportError:
pass
try:
if intro is not None:
self.intro = intro
if self.intro:
self.stdout.write(str(self.intro) + "\n")
stop = None
while not stop:
if self.cmdqueue:
line = self.cmdqueue.pop(0)
else:
if self.use_rawinput:
try:
line = input(self.prompt)
except EOFError:
line = "EOF"
except KeyboardInterrupt:
line = "ctrl_c"
else:
self.stdout.write(self.prompt)
self.stdout.flush()
line = self.stdin.readline()
if not len(line):
line = "EOF"
else:
line = line.rstrip("\r\n")
line = self.precmd(line)
stop = self.onecmd(line)
stop = self.postcmd(stop, line)
self.postloop()
finally:
if self.use_rawinput and self.completekey:
try:
import readline

readline.set_completer(self.old_completer)
except ImportError:
pass

def onecmd(self, line):
"""Interpret the argument as though it had been typed in response
to the prompt.

This may be overridden, but should not normally need to be;
see the precmd() and postcmd() methods for useful execution hooks.
The return value is a flag indicating whether interpretation of
commands by the interpreter should stop.

"""
cmd, arg, line = self.parseline(line)
if not line:
return self.emptyline()
if cmd is None:
return self.default(line)
self.lastcmd = line
if line == "EOF":
self.lastcmd = ""
if line == "ctrl_c":
self.stdout.write("\n")
return
if cmd == "":
return self.default(line)
else:
try:
func = getattr(self, "do_" + cmd)
except AttributeError:
return self.default(line)
return func(arg)


p = MyPrompt()
p.cmdloop()

输出:

python3 test_cmd.py 
(Cmd) test
*** Unknown syntax: test
(Cmd) test1
*** Unknown syntax: test1
(Cmd) test2 <-- Ctrl+C has been pushed and I got a new empty prompt
(Cmd) test3 <-- Ctrl+C has been pushed and I got a new empty prompt
(Cmd) <-- I got a new empty prompt

希望我的解决方案可以帮助您。

关于python - 如何使用 Python cmd shell 捕获 ctrl+c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57056230/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com