2013-02-14 283 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庫的程序,這也很有用。