2013-02-14 96 views
1

我试图在linux中实现一个简单的shell,它应该具有的功能之一是使用户能够按<ctrl+D>并使其停止,无论它在做什么 - 基本上完全是<ctrl+C>在Bash中所做的。简单的Linux Shell。停止命令

现在我想知道最简单的方法来做到这一点,我正在考虑一些可以使当前任务停止的关键侦听器。现在我能想到的唯一方法就是创建一个单独的线程,它会强制停止并将主线程返回到基本状态,并在此处接受新的输入。

一个单独的线程将是“不断”侦听正确按键的唯一方法。

我希望对此有所想法,并可能有更好的方法去做。

[编辑] 我试图做一个简单的shell,它可以执行外部程序,打印/更改目录,打印/设置路径,打印命令历史记录,从历史记录调用命令和打印/设置/删除命令别名。 CTRL-D意味着等同于Bash中的CTRL-C,它允许用户立即退出正在运行的程序,而不是退出shell本身。 [/编辑]

+0

这似乎是一个完全合理的,真实的,建设性的问题给我。提议的/期望的键盘映射是不寻常的,但这并不是错误的;它只是不同而已。你可能会问“你有什么尝试”,但这个问题基本上是合理的。 – 2013-02-15 04:15:38

回答

1

你为什么不处理Ctrl-C

这里只是许多上捕获信号SO disussions之一:Catch Ctrl-C in C

Ctrl-D通常表示EOF在标准输入。你不应该搞砸它。

+0

您的外壳应该不断提示用户输入和阅读,并处理任何用户输入,直到用户输入'exit'或' -D'。请注意,在 后一种情况下,我们实际上正在关闭标准输入,当 试图从中读取时,会发生错误。所以,你需要使用这个作为退出循环的一种方式。 不幸的是,它在规范中已经给出。 – wsmccusker 2013-02-14 23:00:47

+1

我想你已经误解了说明。尝试在常规shell中使用“CTRL-D”。它会退出shell。它应该这样做。但是,如果在当前正在运行的程序中使用CTRL-D,那么shell将不会接收该输入,并且您也不应该尝试这两种输入,因为这意味着当时正在运行的应用程序。 – 2013-02-14 23:29:59

+0

我想我已经理解了你的意思,但是如果我正在钝我很抱歉。我编辑了这个问题,使我想要问的更清楚。 – wsmccusker 2013-02-14 23:51:33

0

除非我在其他答案的评论是不正确的,我认为你应该做的是:

if (!fgets(input, sizeof(input), stdin) == NULL) 
{ 
    ... do cleanup here ... 
    exit(0); 
} 

或东西等同于。

1

如果你想控制-d字符产生中断你,那么:

  1. 您需要EOF字符映射到比控制-d以外的东西。
  2. 您需要将中断字符映射到Control-D

您与<termios.h>头和功能做在POSIX:

你会使用tcgetattr()检索一个struct termios当前属性。您需要制作一份结构副本,然后修改副本,更改c_cc阵列的元素,索引编号为VINTRVEOF(加上您想要进行的任何其他更改),然后设置新属性使用tcsetattr()。您还需要确保您恢复原始终端设置(在退出shell之前,使用tcgetattr()检索的原始属性集合,通过另一次调用tcsetattr())。这可以通过用atexit()注册的处理程序或通过其他机制来完成。在任何情况下,您都应该努力重置终端属性。你无法做任何关于SIGKILL杀死你的事情。

当你正在测试这个,做一个小脚本自己:

echo stty $(stty -g) > sane 
chmod u+x sane 

,在被设计为stty可靠地读取的形式记录当前的(大概是理智)终端设置。如果(当)您的外壳出现问题时,您可以使用Control-JsaneControl-J运行该脚本并将您的终端重置为已知的理智设置。如果您正在开发使用curses库的程序,这也很有用。