Cat
使用 cat 創建文件時,我必須輸入兩次 ctrl+d 才能完成輸入,這是預期的嗎?
我剛剛學會了一個使用命令創建新文件的技巧
cat
。通過我的測試,如果最後一行沒有換行,我必須鍵入ctrl+d
兩次才能完成輸入,如下所示。[root@192 ~]# cat > test 一個 b ctrl+d[root@192 ~]# cat > test 一個 b ctrl+dctrl+d[root@192 ~]#
這是預期的嗎?為什麼會有這種行為?
是的,這是預期的。
我們說 Ctrl-D
cat
在輸入中看到“文件結尾”,然後它停止讀取並退出,但事實並非如此。由於那是在終端上,因此沒有實際的“結束”,實際上它不是真正檢測到的“文件結束” *,*而是任何read()
零字節。通常,
read()
系統呼叫不會返回零字節,除非已知沒有更多可用字節,例如在文件末尾。當從沒有可用數據的網路套接字讀取時,預計新數據將在某個時間到達,因此系統呼叫將阻塞並等待某些數據到達,而不是零字節讀取,或者返回錯誤說它會阻塞。但是,如果連接被關閉,那麼它將返回零字節。再說一次,即使在文件上,在(或過去)結束時讀取也不是無休止的最終結束,因為另一個程序可以將某些內容寫入文件以使其更長,之後新的讀取嘗試將返回更多數據。(這就是一個簡單的實現tail -f
會做的事情。)對於許多將“讀取零字節”視為“檢測到文件結尾”的案例來說,它們恰好工作得很好,以至於在實踐中它們實際上被認為是同一件事。
Ctrl-D 在這裡所做的是告訴終端驅動程序傳遞到目前為止給出的所有內容,即使它還不是完整的行。在一行的開頭,這都是零字節,被檢測為 EOF。但是在字母 之後
b
,第一個 Ctrl-D 發送b
,然後下一個發送在 之後輸入的零字節b
,現在被檢測為 EOF。如果您只是在
cat
沒有重定向的情況下執行,您還可以看到會發生什麼。它看起來像這樣,斜體部分是我輸入的:$*貓* *foo`Ctrl-D`* foo
當按下 Ctrl-D 時,
cat
獲取輸入foo
,將其列印回來並繼續等待輸入。該行看起來像foofoo
,之後沒有換行符,所以游標停留在最後。