Cat

使用 cat 創建文件時,我必須輸入兩次 ctrl+d 才能完成輸入,這是預期的嗎?

  • May 5, 2022

我剛剛學會了一個使用命令創建新文件的技巧cat。通過我的測試,如果最後一行沒有換行,我必須鍵入ctrl+d兩次才能完成輸入,如下所示。

[root@192 ~]# cat > test
一個
b
ctrl+d[root@192 ~]# cat > test
一個
b ctrl+dctrl+d[root@192 ~]#

這是預期的嗎?為什麼會有這種行為?

是的,這是預期的。

我們說 Ctrl-Dcat在輸入中看到“文件結尾”,然後它停止讀取並退出,但事實並非如此。由於那是在終端上,因此沒有實際的“結束”,實際上它不是真正檢測到的“文件結束” *,*而是任何read()零字節。

通常,read()系統呼叫不會返回零字節,除非已知沒有更多可用字節,例如在文件末尾。當從沒有可用數據的網路套接字讀取時,預計新數據將在某個時間到達,因此系統呼叫將阻塞並等待某些數據到達,而不是零字節讀取,或者返回錯誤說它會阻塞。但是,如果連接被關閉,那麼它將返回零字節。再說一次,即使在文件上,在(或過去)結束時讀取也不是無休止的最終結束,因為另一個程序可以將某些內容寫入文件以使其更長,之後新的讀取嘗試將返回更多數據。(這就是一個簡單的實現tail -f會做的事情。)

對於許多將“讀取零字節”視為“檢測到文件結尾”的案例來說,它們恰好工作得很好,以至於在實踐中它們實際上被認為是同一件事。


Ctrl-D 在這裡所做的是告訴終端驅動程序傳遞到目前為止給出的所有內容,即使它還不是完整的行。在一行的開頭,這都是零字節,被檢測為 EOF。但是在字母 之後b,第一個 Ctrl-D 發送b,然後下一個發送在 之後輸入的零字節b,現在被檢測為 EOF。

如果您只是在cat沒有重定向的情況下執行,您還可以看到會發生什麼。它看起來像這樣,斜體部分是我輸入的:

$*貓*
*foo`Ctrl-D`* foo

當按下 Ctrl-D 時,cat獲取輸入foo,將其列印回來並繼續等待輸入。該行看起來像foofoo,之後沒有換行符,所以游標停留在最後。

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