Mục đích của việc đình chỉ trì hoãn (Ctrl-Y) trong Bash là gì?


30

Toàn bộ phần của trang Bash Bash chỉ áp dụng cho biết:

Nếu hệ điều hành mà bash đang chạy hỗ trợ kiểm soát công việc, bash chứa các phương tiện để sử dụng nó. Nhập ký tự treo (thường là ^ Z, Control-Z) trong khi một tiến trình đang chạy khiến quá trình đó bị dừng và trả lại quyền điều khiển cho bash. Nhập ký tự tạm dừng bị trì hoãn (thường là ^ Y, Control-Y) làm cho quá trình bị dừng khi nó cố đọc đầu vào từ thiết bị đầu cuối và điều khiển được trả về bash. Sau đó, người dùng có thể thao tác trạng thái của công việc này, sử dụng bg lệnh để tiếp tục công việc đó trong nền,fglệnh để tiếp tục nó ở phía trước, hoặc lệnh kill để giết nó. A ^ Z có hiệu lực ngay lập tức và có tác dụng phụ bổ sung là khiến đầu ra và kiểu chữ đang chờ xử lý bị loại bỏ.

Tôi chưa bao giờ sử dụng Ctrl- Y; Tôi chỉ tìm hiểu về nó. Tôi đã làm tốt với Ctrl- Z(đình chỉ).

Tôi đang cố gắng tưởng tượng lựa chọn này là . Khi nào nó sẽ hữu ích?

(Lưu ý rằng tính năng này không tồn tại trên tất cả các biến thể Unix. Nó có trên SolarisFreeBSD nhưng không có trên Linux. Cài đặt tương ứng là stty dsusp.)

Có lẽ ít chủ quan hơn: Có bất cứ điều gì có thể được thực hiện với Ctrl- Ymà không thể hoàn thành dễ dàng như vậy với Ctrl- Z?


@Gilles, mặc dù FreeBSD dường như có một stty dsusp, tôi đã không quản lý để gửi nó SIGTSTP khi ^ Y (Tôi đã làm trên Solaris). Có bạn không
Stéphane Chazelas 17/8/2016

Câu trả lời:


23

Từ hướng dẫn 4BSD cho csh :

A ^Zcó hiệu lực ngay lập tức và giống như một ngắt trong đầu ra đang chờ xử lý và đầu vào chưa đọc được loại bỏ khi nó được gõ. Có một khóa đặc biệt khác ^Ykhông tạo tín hiệu STOP cho đến khi chương trình cố gắng đọc (2). Điều này có thể được gõ một cách hữu ích khi bạn đã chuẩn bị một số lệnh cho một công việc mà bạn muốn dừng lại sau khi nó đã đọc chúng.

Vì vậy, mục đích là để nhập nhiều đầu vào trong khi đầu vào đầu tiên đang được xử lý và dừng công việc sau khi hoàn thành.


Mô tả này là khác biệt tinh tế với hướng dẫn bash. "... không tạo ra một tín hiệu STOP cho đến khi một nỗ lực chương trình để đọc nó. " Nó giống như tất cả mọi thứ trong đầu vào âm thanh dòng lên đến các ^Ysẽ được đọc thành công, và sau đó khi ^Yđược nhấn quá trình này sẽ được ngừng lại. Tôi đang đọc cái này phải không?
tự đại diện

@Wildcard trong thử nghiệm của tôi trên Mac OS X, quá trình này bị dừng trước khi read () trả về (nhưng sau khi gọi để đọc () sẽ trả về Y chạy) và sau khi được tiếp tục, nó sẽ nhận được đầu vào từ trước ^ Y . Tôi nghĩ rằng vì điều này đã được dự định sẽ được sử dụng, tuy nhiên, nó sẽ được sử dụng ở đầu một dòng, vì vậy hành vi trong trường hợp này sẽ không thành vấn đề. Tôi nghi ngờ rằng trong mã thực tế, nó bị treo khi ^ Y sẽ được sao chép vào bộ đệm đọc quy trình người dùng.
Random832

Tôi đã đúng, trong chức năng ttread của hạt nhân BSD ban đầu, bạn có thể thấy điều này và OSX hiện đại
Random832

Nhưng, khi quá trình được nối lại, cuộc gọi sẽ thành công và sẽ chứa dữ liệu bạn đã nhập vào thiết bị đầu cuối của mình trước đó ^Y, ngay cả khi bạn đã từ chối quy trình và đóng thiết bị đầu cuối của mình trước khi quá trình được tiếp tục. Đúng? ( "... sau khi được nối lại, nó nhận được đầu vào từ trước ^ Y." Đó là điều tôi muốn nói; tôi thường không giao dịch bằng mã C.) :)
Wildcard

Vâng. Và nó trở lại mà không có dòng mới ở cuối, điều này không bình thường đối với việc đọc ở chế độ chính tắc [tương tự như nếu bạn đã gõ một số văn bản và sau đó nhấn ^ D một lần] Tôi nghi ngờ họ không nghĩ về trường hợp này rất nhiều, vì nó thực sự có ý định được gõ vào đầu một dòng.
Random832

11

Nói rằng có một vòng lặp đọc đầu vào và thực thi. Có thể hữu ích khi để tác vụ hoàn thành lệnh hiện tại mà nó tính toán, mà không làm gián đoạn nó trước khi nó quay trở lại dòng lệnh cho một lệnh mới. Vì vậy, để kết thúc một chu kỳ. Điều này kết thúc vòng lặp một cách duyên dáng và ngăn nó chạy lại nếu readbị hạn chế thời gian chờ.


Nhưng nếu nó cố gắng đọc đầu vào từ thiết bị đầu cuối, nó sẽ dừng tại thời điểm đó (và đợi đầu vào của bạn), và sau đó bạn có thể làm ^Zđiều đó .
tự đại diện

Vâng. Xem cập nhật.
Tomasz

Kiểm tra một cái nữa. @Wildcard
Tomasz

1
Nhưng nếu nó hết thời gian, nó cũng sẽ kết thúc một cách duyên dáng nếu bạn không làm gì đặc biệt?
Daniel Wagner

1
Nó có thể. Nhưng nó cũng có thể tiếp tục và làm một số công việc mặc định.
Tomasz

4

Tôi có thể nghĩ về một kịch bản có thể hữu ích, nhưng đó là một tình huống khó khăn.

Giả sử bạn đang gỡ lỗi một tập lệnh đang ghi các tệp tạm thời mà bạn muốn phân tích trước khi chúng bị xóa như một phần của thói quen dọn dẹp.

Bạn có thể thêm một read foonơi nào đó sau khi các tệp được ghi (nhưng trước khi dọn dẹp), hãy chạy tập lệnh và nhấn Ctrl- Ykhi chúng được tạo. Sau đó, bạn sẽ được thả xuống một dấu nhắc với tập lệnh bị treo trong nền để làm bất cứ điều gì bạn cần làm và sau đó có thể fgcho phép tập lệnh hoàn tất.


1
Có vẻ như không thể, bởi vì tập lệnh sẽ chờ đầu vào nào. Vì vậy, bạn có thể dễ dàng xem nó để nhắc bạn nhập liệu và sau đó tạm dừng nó với ^Z. Nói cách khác: sau khi bạn gõ fgbạn sẽ phải cung cấp cho các kịch bản một số đầu vào nào trước khi nó sẽ tiếp tục. Do đó câu hỏi của tôi; Tôi vẫn không thấy quan điểm của ^Y. (Tuy nhiên, cảm ơn vì đã trả lời!) :)
Wildcard

2

Kịch bản duy nhất tôi có thể nghĩ đến (và thậm chí tôi không thấy nó rất thuyết phục), là nếu bạn muốn sử dụng một số loại trước cho lệnh shell. Nói rằng một số lệnh đang chạy sẽ đọc đầu vào một thời gian trong tương lai. Sau đó, bạn có thể ^ Y nó, và sau đó gõ ngay lệnh shell tiếp theo mà bạn muốn thực hiện khi lệnh đang chạy bị đình chỉ. Tôi không nghĩ rằng tôi đã thực sự sử dụng điều này trong vài thập kỷ sử dụng BSD Unix.

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.