Cat
使用 Ctrl+D 和 Ctrl+C 終止 cat 命令有什麼區別?
我有以下兩個測試文件:
test1 test2
兩者都是空白的。現在我發出以下命令:
$ cat > test1
Enter
This is a test file
Enter
Ctrl
+D
$ cat > test2
Enter
This is another test file
Enter
^C
Ctrl
+C
$
現在我檢查兩個文件的內容
$ cat test1 This is a test file $ cat test2 This is another test file $
那麼如果我們使用上述兩種方法來達到相同的結果,結果是否有任何真正的區別?
命令執行時
cat
,終端處於規範輸入模式。簡而言之,這意味著終端的線路規則正在處理線路編輯,並響應為終端配置的所有特殊字元stty
(可通過命令查看和設置)。該
cat
命令只是read()
從其標準輸入 ing 直到read()
呼叫返回讀取的零字節,即命中文件結尾的 POSIX 約定。終端並沒有真正的“結束”。但是存在
read()
終端設備返回零字節的情況。當行規程接收到“EOF”特殊字元時,無論當時發生了什麼配置,它都會導致read()
返回當時編輯緩衝區中的任何內容。如果編輯緩衝區為空,則返回從 讀取的零字節read()
,從而導致cat
退出。
cat
也退出以響應其預設操作是終止程序的信號。線路規程還生成響應特殊字元的信號。“INTR”和“QUIT”特殊字元導致INT
和QUIT
信號被發送到前台程序(組),該程序將是/包含該cat
程序。這些信號的預設動作是終止cat
程序。這導致了可觀察到的差異:
Ctrl
+D
只有當它是 EOT 特殊字元時才有這個動作。通常是這種情況,但不一定是這種情況。類似地,Ctrl
+C
僅當它是 INTR 特殊字元時才起作用。Ctrl
+當該行實際上不是空的時,D
不會導致終止。但是,由+cat
生成的中斷會發生。Ctrl``C
cat
如果發現它指向一個文件,C 語言中的naïve 實現將阻止緩衝區標準輸出,如問題中所示。從理論上講,如果cat
被SIGINT
.實際上,BSD 和 GNU C 庫實現了 C 或 C++ 語言標準中未描述的緩沖模式。重定向到文件或管道時的標準輸出是智能緩衝的。它是塊緩衝的;read()
除了每當 C 庫從任何對終端設備打開的文件描述符中發現自己即將開始新行時,它都會刷新標準輸出。cat
(嚴格來說,BSD 和 GNU C 庫並沒有完全實現相同的語義,並且做得更多,但這種行為是一個常見的子集。)因此,當建立在這樣的之上時,中斷信號不會導致緩衝輸出失去。 C 庫。- 當然,如果
cat
是命令管道的一部分,則其他一些程序可能正在緩衝數據,cat
在這些數據到達輸出文件之前的下游。因此,當線路規程發送SIGINT
時(預設情況下)終止管道中的所有程序,緩衝且尚未寫入的輸入數據將失去;而cat
使用“EOF”特殊字元正常終止將導致管道正常終止,所有數據在下游程序從其標準輸入接收到EOF指示之前傳遞給下游程序*。*read()
請注意,這與互動式 shell 從您那裡讀取一行輸入時發生的情況幾乎沒有關係。當您的 shell 等待輸入時,終端處於非規範輸入模式,在該模式下,行規則不對特殊字元進行任何特殊處理。您的 shell 如何處理
Ctrl
+D
和Ctrl
+C
完全取決於您的 shell 使用的輸入編輯庫(libedit、readline 或 ZLE)以及該編輯庫的配置方式(使用鍵綁定等)。進一步閱讀
- POSIX 終端介面。維基百科。