Ctrl + D để kết thúc đầu vào dòng thiết bị đầu cuối


21

Nếu tôi làm

$ cat > file.txt

văn bản Ctrl- DCtrl-D

Câu hỏi 1: Nếu tôi không nhấn enter, tại sao tôi phải nhấn Ctrl- Dhai lần?

Nếu tôi làm

$ cat > file.txt

pa bam pshhh Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
$ cat > file.txt

pa bam pshhh

Ctrl-Z

[2]+  Stopped         cat > file.txt
$ cat file.txt
pa bam pshhh

Tại sao lần thứ hai tập tin có 1 dòng?


2
Chủ đề này dưới ô trang web stackexchange có câu trả lời bạn đang xem: stackoverflow.com/questions/7369170/ . Hy vọng nó giúp.

Vâng, mặc dù không liên quan đến trăn, câu hỏi của tôi là một bản sao.
sương mù

Khi bạn gõ ctrl-z, bạn có thực sự nhận được một dấu nhắc shell mới hay bạn cũng nhận được thông báo về việc catbị dừng?
Đánh dấu Plotnick

Tôi sẽ cập nhật câu hỏi
sương mù

Câu trả lời:


30

Trong Unix, hầu hết các đối tượng bạn có thể đọc và ghi - các tệp thông thường, đường ống, thiết bị đầu cuối, ổ đĩa thô - đều được tạo ra để giống với các tệp.

Một chương trình như catđọc từ đầu vào tiêu chuẩn của nó như thế này:

n = read(0, buffer, 512);

yêu cầu 512 byte. nlà số byte thực sự đọc hoặc -1 nếu có lỗi.

Nếu bạn đã làm điều này nhiều lần với một tệp thông thường, bạn sẽ nhận được một loạt các lần đọc 512 byte, sau đó đọc ngắn hơn một chút ở phần đuôi của tệp, sau đó 0 nếu bạn cố đọc qua phần cuối của tệp. Vì vậy, catsẽ chạy cho đến khi n<= 0.

Đọc từ một thiết bị đầu cuối là hơi khác nhau. Sau khi bạn nhập một dòng, kết thúc bằng Enterkhóa, readchỉ trả về dòng đó.

Có một vài ký tự đặc biệt bạn có thể gõ. Một là Ctrl-D. Khi bạn nhập cái này, hệ điều hành sẽ gửi tất cả dòng hiện tại mà bạn đã nhập (chứ không phải Ctrl-Dchính nó) đến chương trình đang đọc. Và đây là điều tình cờ: nếu Ctrl-Dlà ký tự đầu tiên trên dòng, chương trình được gửi một dòng có độ dài 0 - giống như chương trình sẽ thấy nếu nó chỉ đến cuối một tệp thông thường. cat không cần phải làm gì khác , cho dù đó là đọc từ một tệp thông thường hoặc thiết bị đầu cuối.

Một nhân vật đặc biệt khác là Ctrl-Z. Khi bạn nhập nó, bất cứ nơi nào trong một dòng, hệ điều hành sẽ loại bỏ bất cứ thứ gì bạn đã nhập cho đến thời điểm đó và gửi tín hiệu SIGTSTP đến chương trình, thường dừng (tạm dừng) nó và trả lại quyền điều khiển cho trình bao.

Vì vậy, trong ví dụ của bạn

$ cat > file.txt
pa bam pshhh<Ctrl+Z>
[2]+  Stopped         cat > file.txt

bạn đã gõ một số ký tự bị loại bỏ, sau đó catbị dừng mà không ghi bất cứ điều gì vào tệp đầu ra của nó.

$ cat > file.txt
pa bam pshhh
<Ctrl+Z>
[2]+  Stopped         cat > file.txt

bạn đã gõ vào một dòng, nó catđọc và ghi vào tệp đầu ra của nó, rồi Ctrl-Zdừng lại cat.


1
những điều này chỉ thực sự của thiết bị đầu cuối chế độ kinh điển . Và thậm chí trong trường hợp đó họ có thể được thay đổi.
mikeerv

@mikeerv Điều đó đúng. Ở đây, tôi muốn giải thích những gì OP đang nhìn thấy. Tôi cũng đã xem xét mô tả chế độ đầu cuối thô / -ican, các ký tự đặc biệt khác, cách chúng có thể được tùy chỉnh, chúng khác nhau như thế nào bởi HĐH, v.v. nhưng không muốn đưa ra câu trả lời quá lâu.
Đánh dấu Plotnick

Có phải điều trên có nghĩa là nếu đầu vào không được thông qua cat, thì một chương trình đọc dữ liệu từ bàn phím và không dừng lại lần đầu tiên readmang lại số 0 có thể tiếp tục và số lượng điều khiển-D yêu cầu sẽ được xác định bởi số lượng số 0 liên tiếp mà chương trình yêu cầu để quyết định nó đã được thực hiện?
supercat

@supercat Một chương trình có thể tiếp tục đọc nếu nó muốn. Trong extrình chỉnh sửa, nếu bạn nhập control-D là ký tự đầu tiên của một dòng, trình chỉnh sửa sẽ hiển thị cho bạn một vài dòng của chương trình thay vì thoát. (Trong exvi, Control-D là một bản ghi nhớ cho "xuống"). Và với nhiều shell, nếu bạn gõ Control-D nhưng có các công việc đang chạy trong nền, shell sẽ thông báo cho bạn về điều này thay vì thoát, nhưng nếu bạn gõ lại Control-D, shell sẽ quyết định rằng bạn thực sự muốn thoát ra và sẽ làm như vậy.
Đánh dấu Plotnick

@MarkPlotnick: Có cách nào mà những trục trặc không byte này có thể được gửi qua đường ống không?
supercat

19

Đó là vì Ctrl+ Dlà một hack.

Trong sâu thẳm, Ctrl+ D(mặc dù được gọi là eofký tự ) không thực sự có nghĩa là phần cuối của tệp: nó có nghĩa là gửi gửi đầu vào đang chờ xử lý cho ứng dụng ngay bây giờ. Điều này thực sự gần với nghĩa của Ctrl+ M( eol), sẽ gửi đầu vào đang chờ xử lý cộng với một dòng mới.

Khi bạn nhấn Ctrl+ Dngay sau dấu Ctrl+ M(tức là ở đầu dòng) hoặc sau dấu Ctrl+ khác D, đầu vào đang chờ xử lý trống. Do đó, ứng dụng nhận được 0 byte đầu vào. Trong một readcuộc gọi, đọc 0 byte báo hiệu kết thúc tập tin.


Khi bạn nhấn Ctrl+ Z, đầu vào đang chờ xử lý sẽ bị loại bỏ. Do đó, chỉ những gì đã được gửi đến ứng dụng (đó là cat) bằng cách nhập một dòng mới hoặc Ctrl+ Dtrước khi nhấn Ctrl+ Zđược xử lý.


1
Thông tin thêm về ctrl + D từ một trong những câu trả lời của Gille có thể được tìm thấy ở đây .
Ramesh

Như bạn đã nói, Ctrl-D không có nghĩa là kết thúc tập tin. Trong thực tế lý do không có nghĩa là vì Ctrl-D là EOT (cuối văn bản).
H2ONaCl
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.