Cat

使用 Ctrl+D 和 Ctrl+C 終止 cat 命令有什麼區別?

  • July 18, 2017

我有以下兩個測試文件:

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”特殊字元導致INTQUIT信號被發送到前台程序(組),該程序將是/包含該cat程序。這些信號的預設動作是終止cat程序。

這導致了可觀察到的差異:

  • Ctrl+D只有當它是 EOT 特殊字元時才有這個動作。通常是這種情況,但不一定是這種情況。類似地,Ctrl+C僅當它是 INTR 特殊字元時才起作用。
  • Ctrl+當該行實際上不是空的時,D不會導致終止。但是,由+cat生成的中斷會發生。Ctrl``C
  • cat如果發現它指向一個文件,C 語言中的naïve 實現將阻止緩衝區標準輸出,如問題中所示。從理論上講,如果catSIGINT.實際上,BSD 和 GNU C 庫實現了 C 或 C++ 語言標準中未描述的緩沖模式。重定向到文件或管道時的標準輸出是智能緩衝的。它是塊緩衝的;read()除了每當 C 庫從任何對終端設備打開的文件描述符中發現自己即將開始新行時,它都會刷新標準輸出。cat(嚴格來說,BSD 和 GNU C 庫並沒有完全實現相同的語義,並且做得更多,但這種行為是一個常見的子集。)因此,當建立在這樣的之上時,中斷信號不會導致緩衝輸出失去。 C 庫。
  • 當然,如果cat是命令管道的一部分,則其他一些程序可能正在緩衝數據,cat在這些數據到達輸出文件之前的下游。因此,當線路規程發送SIGINT時(預設情況下)終止管道中的所有程序,緩衝且尚未寫入的輸入數據將失去;而cat使用“EOF”特殊字元正常終止將導致管道正常終止,所有數據在下游程序從其標準輸入接收到EOF指示之前傳遞下游程序*。* read()

請注意,這與互動式 shell 從您那裡讀取一行輸入時發生的情況幾乎沒有關係。當您的 shell 等待輸入時,終端處於非規範輸入模式,在該模式下,行規則不對特殊字元進行任何特殊處理。您的 shell 如何處理Ctrl+DCtrl+C完全取決於您的 shell 使用的輸入編輯庫(libedit、readline 或 ZLE)以及該編輯庫的配置方式(使用鍵綁定等)。

進一步閱讀

引用自:https://unix.stackexchange.com/questions/379347