Cat
shell中的cat命令在通過串口接收EOT時不會終止
我有 shell/perl 腳本,它啟動
cat
從外部設備接收傳入串列數據的命令。外部設備設計為在完成傳輸時發送 EOT 字元。但是該
cat
命令在收到 EOT 後永遠不會終止,實際上它會列印出所有的串列數據,然後是帶有 (0004) 的小框,它是 EOT 的十六進制值。當我將所有這些數據通過管道傳輸到文件中並在 VIM 中打開時,我確實看到了由
^D
.我想知道為什麼終端上的 cat 命令檢測不到 EOT?
stty --all --file=(serial_port) yeilds
:speed 115200 baud; rows 0; columns 0; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts -cdtrdsr -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8 -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke
CTRL+D 在這裡毫無意義——它只是另一個字節。這是因為您的串列終端未配置為處理它。具體來說,您實際上處於raw-mode或Non-Canonical Input Mode。看到輸出中的
-icanon
標誌了stty -a
嗎?那收緊它。以下是 POSIX 描述終端應考慮 EOF 字元的方式:
- EOF
- 輸入的特殊字元,如果設置了ICANON標誌,則可以辨識。收到後,所有等待讀取的字節立即傳遞給程序,無需等待換行符,EOF被丟棄。因此,如果沒有等待的字節*(即,EOF發生在行的開頭),則應從 中返回字節計數為零
read()
,表示文件結束指示。如果設置了ICANON*,則處理時應丟棄EOF字元。但是您不是在使用規範終端工作 - 您正在使用一個終端,只要有至少一個字節要推送,就會在被詢問時將任何/所有數據推送給任何閱讀器。終端不會按行緩衝輸入 - 因此它不能用空讀取替換 EOF 字節 - 相反,它只是推送字節,這
cat
只會鼓勵它繼續閱讀。