Dừng đầu ra từ một chương trình chạy trong phiên SSH NGAY


18

Vấn đề

Tôi thực thi lệnh tạo ra rất nhiều thông tin thông qua SSH. Ví dụ, tôi dại dột thêm thông tin gỡ lỗi bên trong một vòng lặp thực thi hàng triệu lần hoặc chỉ chạy cat /dev/urandomđể đá.

Các thiết bị đầu cuối tràn ngập thông tin.

Ví dụ những gì tôi đang nói về

Tôi muốn chấm dứt lệnh ASAP và sửa chương trình của tôi. Tôi không quan tâm nó in cái gì. Bây giờ, điều là tôi nhấn Ctrl+ CASAP (trong ví dụ trên tôi đã nhấn nó ngay sau khi chạy lệnh), nhưng vẫn cần thời gian để in tất cả thông tin tôi thậm chí không cần .

Những gì tôi đã thử

Tôi đã thử nhấn Ctrl+ Cmạnh đến nỗi nó có kết quả hài hước khi thiết bị đầu cuối cuối cùng đã bắt kịp:

OUTPUT HERE^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
^C^C

^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
^C^C^C^C^C^C^C^C^C^C^C^C^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C
rr-@burza:~/xor$ ^C

Tôi cũng đọc về Ctrl+ Smà dường như được sử dụng để nói với thiết bị đầu cuối "dừng đầu ra, tôi cần bắt kịp" nhưng dường như nó không làm gì cả.

Chi tiết linh tinh

Tôi muốn không thay đổi lệnh tôi chạy để tôi có thể tự cứu mình trong mọi tình huống, ngay cả khi tôi không nhớ rằng chương trình tôi chạy có thể kết thúc như thế.

Máy khách SSH của tôi chạy trên Cygwin ( CYGWIN_NT-6.1-WOW64 luna 1.7.30(0.272/5/3) 2014-05-23 10:36 i686 Cygwin) trong MinTTY với loại thiết bị đầu cuối được đặt thành xterm-256color.

Máy chủ SSH chạy trên Debian ( Linux burza 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 i686 i686 GNU/Linux).


Trên hệ thống nào bạn đang chạy các chương trình thực tế tạo ra đầu ra? Linux, Unix hay Windows? Linux và UNIX phải chấp nhận Ctrl-O, có nghĩa là "loại bỏ bất kỳ đầu ra nào được ghi vào thiết bị đầu cuối này".
Đánh dấu Plotnick

Máy chủ chạy trên Debian. Chỉnh sửa câu hỏi. Ctrl-O dường như không làm gì cả. Có lẽ đó là điều khách hàng?
rr-

Bạn có thể thử bắt đầu xterm của mình với -jtùy chọn, để cho phép cuộn nhảy. Vấn đề cơ bản là điều khiển từ xa có thể gửi dữ liệu nhanh hơn cửa sổ đầu cuối có thể hiển thị nó - theo mặc định, nó phải bitblt nội dung của cửa sổ mỗi khi một dòng mới được in. Toàn bộ dữ liệu có thể được lưu vào bộ đệm khi hệ thống từ xa nhận được hệ thống từ xa và chương trình đầu cuối của bạn sẽ cố gắng hiển thị tất cả dữ liệu đó.
Đánh dấu Plotnick

Chỉ là một ý tưởng: nếu bạn có một số lệnh chính xác mà bạn thường vô tình thực hiện và chúng tạo ra rất nhiều đầu ra, tại sao không thêm một số bí danh vào .bashrc?
psimon

Bạn có thể sử dụng mosh thay vì ssh: mosh.mit.edu
gmatht

Câu trả lời:


5

Một số đầu ra đó sẽ được đệm. Bạn gửi Ctrl+ Cđến đầu cuối từ xa làm gián đoạn chương trình đang chạy. Chương trình tồn tại và shell gửi các ký tự để hiển thị lại cho bạn lời nhắc. Trước khi lời nhắc được hiển thị, trước tiên, màn hình của bạn sẽ hiển thị tất cả dữ liệu đã được đệm và đang trên đường đến với bạn.

Những gì bạn đang yêu cầu là chương trình dừng lại và dữ liệu quá cảnh sẽ biến mất. Điều đó không thể xảy ra vì nó đã trên đường.

Cách duy nhất bạn có thể đảm bảo rằng bạn không thấy dữ liệu này là thoát khỏi thiết bị đầu cuối ở cuối và sau đó kết nối lại với điều khiển từ xa của bạn - nhưng đó có lẽ là nỗ lực hơn nhiều so với việc chờ dữ liệu được đệm hiển thị.


10

Tôi thường chạy đầu ra vào less để có thể giết nó thông qua lessthay vì sử dụng qkhóa.

$ cmd | less

Thí dụ

$ cat /dev/urandom | less

   ss # 2

Sau khi nhấn q+ Enternó sẽ thoát và quay trở lại thiết bị đầu cuối bình thường của bạn, để nó trở nên đẹp và sạch sẽ.

Tại sao điều đó xảy ra?

Vấn đề bạn gặp phải là có bộ đệm (đối với STDOUT) đang được xếp hàng với đầu ra của màn hình. Những bộ đệm này được lấp đầy nhanh đến mức bạn không thể làm gián đoạn nó đủ nhanh để ngăn chặn nó.

                                    ss # 1

Để vô hiệu hóa / giới hạn hiệu ứng này, bạn có thể vô hiệu hóa bộ đệm STDOUT, điều này sẽ khiến mọi thứ phản ứng nhanh hơn một chút bằng cách sử dụng stdbuf , nhưng bạn có thể phải chơi với các cài đặt này để có được mọi thứ theo cách bạn muốn. Để giải nén STDOUT, bạn có thể sử dụng lệnh này:

$ stdbuf -o0 <cmd>

Trang nam cho stdbuf biết chi tiết các tùy chọn theo ý của bạn:

    If MODE is 'L' the corresponding stream will be line buffered.  This 
    option is invalid with standard input.

    If MODE is '0' the corresponding stream will be unbuffered.

    Otherwise MODE is a number which may be followed by one of the 
    following: KB 1000, K 1024, MB 1000*1000, M 1024*1024, and so
    on for G, T, P, E, Z, Y.  In this case the corresponding stream will be 
    fully buffered with the  buffer  size  set  to  MODE
    bytes.

Để có một nền tảng tốt về cách hoạt động của bộ đệm, tôi khuyên bạn nên xem qua Pixel Beat có khớp nối này có tiêu đề: đệm trong các luồng tiêu chuẩn . Nó thậm chí bao gồm hình ảnh đẹp.

Tài liệu tham khảo


Điều đó hợp lý miễn là bạn nhớ thêm |lessvào cmd, điều không may là tôi thường không làm. Nếu bạn chạy cmd, bạn vẫn cần đợi cho đến khi hoàn thành việc in kết quả được tính toán trước khi nhận ^C.
rr-

1
Điều đó không thực sự giải thích những gì đang xảy ra. Rốt cuộc, không có đường ống nào liên quan, vậy bạn đang đề cập đến bộ đệm nào?
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles - xin lỗi, bộ đệm sẽ là bộ đệm cho màn hình.
slm

Đệm gì? Trong nhân? Trong xterm?
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles - cho tôi một phút, tôi đang tìm chi tiết 8-)
slm

3

Có nhiều cấp độ đệm. Khi bạn nhấn Ctrl+ C, điều này sẽ ngăn chương trình phát dữ liệu đến thiết bị đầu cuối. Điều này không ảnh hưởng đến dữ liệu mà trình giả lập thiết bị đầu cuối chưa hiển thị.

Khi bạn đang hiển thị dữ liệu ở tốc độ rất cao, thiết bị đầu cuối không thể theo kịp và sẽ bị lag. Đó là những gì đang diễn ra ở đây: hiển thị văn bản đắt hơn nhiều so với việc tạo ra những con số ngẫu nhiên này. Có, ngay cả với một phông chữ bitmap - tạo ra các số ngẫu nhiên có chất lượng mật mã là rất rẻ so với. (Tôi vừa thử trên máy của mình và quá trình X đã bão hòa CPU, vớixterm tham gia một vài% và cat(mà thế hệ số ngẫu nhiên được hạch toán chống lại) chỉ đạt 1%. Và điều đó với một phông chữ bitmap.)

Nếu bạn muốn dừng ngay bây giờ, hãy tắt trình giả lập thiết bị đầu cuối. Nếu bạn không muốn làm điều đó, ít nhất là thu nhỏ cửa sổ; trình giả lập thiết bị đầu cuối thông minh (như xterm) sẽ không ánh xạ cửa sổ, giúp tiết kiệm thời gian CPU X, do đó, rác sẽ hiển thị nhanh hơn. Máy chủ X có mức độ ưu tiên cao, vì vậy điều này sẽ tạo ra sự khác biệt lớn đối với khả năng phản hồi của máy trong khi xterm đang xử lý dữ liệu ở chế độ nền.

Khi tất cả điều này đang diễn ra trong một vỏ từ xa, độ trễ thậm chí còn tồi tệ hơn, bởi vì dữ liệu được tạo ra cattrước tiên phải thông qua kết nối SSH. Báo chí Ctrl+ của bạn Ccũng phải thông qua kết nối SSH; nó được ưu tiên cao hơn một chút (nó được gửi ra khỏi ban nhạc), nhưng điều đó vẫn cần một chút thời gian để tích lũy nhiều sản lượng hơn. Không có cách nào để ngăn chặn dữ liệu quá cảnh khi đóng kết nối SSH (bạn có thể thực hiện bằng cách nhấn Entersau đó ~.).


Vấn đề liên quan đến SSH cùng. Bộ đệm STDOUT không nên được sử dụng trong chế độ tương tác nhưng SSH không thể xử lý chế độ tương tác đúng cách. Mặc dù rất nhiều đầu ra có thể bị treo trong giao dịch, đó là quá trình SSH nhận Ctrl + C, do đó, anh ta có trách nhiệm phải giết đầu ra khi không thể chuyển Ctrl + C sang điều khiển từ xa.
dùng4674453

@ user4674453 Uh? Ctrl + C không được phép giết đầu ra cục bộ. Đó hoàn toàn không phải là công việc của nó. Nó được cho là được chuyển đến phía xa, có thể hoặc không thể giết quá trình từ xa.
Gilles 'SO- ngừng ác'

"Nó được cho là được chuyển đến phía xa, có thể hoặc không thể giết chết quá trình từ xa." - nó cũng không phải làm điều đó. Tín hiệu KILL, Ctrl + C đang phát hành một trong số chúng, chỉ dành cho quy trình cục bộ. Nếu nó không được sử dụng cho quy trình địa phương, khái niệm "được cho là" hoàn toàn không áp dụng.
dùng4674453

@ user4674453 Số Ctrl + C không phải là tín hiệu tiêu diệt. Đó là một tín hiệu ngắt. Vai trò của nó là trở về một dấu nhắc tương tác. Nó chỉ giết các chương trình không có dấu nhắc tương tác để quay lại.
Gilles 'SO- ngừng trở nên xấu xa'

"Đó là một tín hiệu ngắt." Đó là một đối số để giết lệnh, do đó nó là một tín hiệu tiêu diệt. Đôi khi nó được gọi là tín hiệu POSIX nếu bạn muốn. "Vai trò của nó là quay trở lại một dấu nhắc tương tác. Nó chỉ giết các chương trình không có dấu nhắc tương tác để quay lại." Chính xác!!! Và SSH không làm điều đó như mong đợi.
dùng4674453

1

Nó phải là đủ để tìm một cách để killcác catlệnh.
Đối với các đề xuất sau, bạn có thể cần mở kết nối ssh thứ hai.

  • Hiếm khi CTRL+zcó thể hiệu quả hơn CTRL+c: nó có thể trả lời nhanh hơn. Sau đó, bạn tạm dừng lệnh, bạn có thể giết nó bằng kill %1hoặc bất cứ thứ gì là số công việc của nó.
    Điều này với hy vọng rằng bạn vẫn có thể đọc bất cứ thứ gì từ màn hình (một văn bản nhị phân ngẫu nhiên tràn ngập có thể dễ dàng làm rối bộ ký tự của bạn).
    Như Gilles đã nhớ nếu bạn thu nhỏ cửa sổ, có lẽ hệ thống sẽ đọc yêu cầu ngắt nhanh hơn bạn để giết tiến trình. Vì vậy, đình chỉ / phá vỡ, giảm thiểu, chờ một chút, tối đa hóa một lần nữa, cũng có thể là một giải pháp.
    Tất nhiên thông qua kết nối ssh tôi mong rằng bạn cần tuy nhiên phải chờ một thời gian.

  • Trong một thiết bị đầu cuối / phiên khác, bạn có thể hỏi pgrep cat(nếu cat là lệnh được gọi) và xác định tiến trình mèo đang sử dụng nhiều cpu của bạn. Bạn có thể xác định nó với độ chính xác cao hơn với pstree:

    mèo pgrep | awk '{in "pstree -sp" $ 1}' | sh | grep sshd

    trả lời với một đầu ra như

    init (1) ───sshd (1062) ───sshd (22884) ───sshd (22951) ───bash (22957) ───cat (23131)

    Trong trường hợp này, sau khi bạn chỉ phải giết con mèo PID: giết 23131

Chú thích:


1

Tôi có cùng một vấn đề và không hài lòng với câu trả lời ở đây vì vậy tôi đã đào sâu hơn. Những người khác đã đề cập đến lệnh của bạn là xuất dữ liệu nhanh hơn so với ssh của bạn, do đó, bộ đệm dữ liệu và bộ đệm không thể dừng lại.

Để khắc phục điều này, hãy tránh việc đệm bằng cách điều chỉnh đầu ra lệnh của bạn đến tốc độ tối đa mà phiên ssh của bạn có thể thực hiện, các lệnh đã tồn tại để thực hiện việc này.

Thiết lập, đầu tiên tìm ra tỷ lệ tối đa phiên của bạn:

# Get transfer <TIME> of a large file (>10MB preferable)
/usr/bin/time -f "%e" cat <FILENAME>

# Get file <SIZE> in bytes
stat --printf="%s\n" <FILENAME>

# Calculate <RATE>
echo "<SIZE> / <TIME>" | bc

Cuối cùng, điều tiết các lệnh thực sự của bạn cho phù hợp.

<YOUR_COMMAND> | pv -qL <RATE>

Thí dụ:

/usr/bin/time -f "%e" cat large_reference_file.txt
31.26

stat --printf="%s\n" cat large_reference_file.txt
17302734

echo "17302734 / 31.26" | bc
553510

# Throttle my command to 553510B/s
cat some_other_file.txt | pv -qL 553510

Thỉnh thoảng bạn có thể muốn giảm RATE một chút trong trường hợp tốc độ kết nối của bạn giảm xuống một chút. Nếu nó giảm, hành vi sẽ trở lại vấn đề, một ctrl-c không phản hồi.

Tùy chọn bí danh mèo điều tiết:

# bash
alias tcat='tcat(){ cat $@ | pv -qL 400k ; }; tcat'

# tcsh
alias tcat 'cat \!* | pv -qL 400k'

# usage: tcat <FILENAME>

Bây giờ ctrl-c hoạt động như mong đợi, ngay lập tức giết chết đầu ra vì rất ít nếu có bất kỳ bộ đệm nào.


catđầu ra hiếm khi là một vấn đề, không giống như các phần mềm khác. Tác giả chỉ sử dụng nó làm ví dụ. Vấn đề thường là do các phần mềm khác có thể không rõ ràng nếu nó sẵn sàng tạo ra nhiều đầu ra. Sử dụng bất kỳ loại tiền tố hoặc lệnh postfix là không có giải pháp, vì phải mất thời gian để nhập nó. Sẽ không có bất kỳ lợi ích trong kết quả.
dùng4674453

0

Có một phần mềm trên Linux giải quyết chính xác điều này vấn đề (một vài thứ khác nữa). Bạn cũng có thể gọi nó từ trình giả lập thiết bị đầu cuối trong Windows (dường như bạn đang sử dụng Windows?).

Hãy thử mosh , một sự thay thế cho nhị phân SSH. Nó hoạt động chính xác như SSH (bạn có thể làm mosh user@hostnamethay vìssh user@hostname và nó sẽ hoạt động chính xác như bạn mong đợi, thậm chí sẽ thực hiện xác thực khóa riêng, v.v.

Về cơ bản, nó chạy một tiến trình riêng biệt trên máy chủ để đệm các gói. Vì vậy, khi bạn nhấn Ctrl + C trên mosh, nó sẽ truyền tải điều này đến máy chủ từ xa, sau đó sẽ ngừng gửi thêm thông tin. Ngoài ra, nó cũng sẽ dự đoán kết quả của tổ hợp phím, giúp bạn tiết kiệm một vài mili giây mỗi lần bạn nhấn phím.

Nhược điểm: Hiện tại không thể cuộn lên trong lịch sử trong khi sử dụng mosh.

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.