지금 SSH 세션에서 실행되는 프로그램의 출력 중지


18

문제

SSH를 통해 많은 정보를 출력하는 명령을 실행합니다. 예를 들어, 백만 번 실행되거나 cat /dev/urandom킥을 위해 실행되는 루프 내에 어리석게 디버그 정보를 추가 합니다.

터미널에 정보가 넘칩니다.

내가 말하는 것의 예

최대한 빨리 명령을 종료하고 프로그램을 수정하고 싶습니다. 나는 그것이 무엇을 인쇄하는지 상관하지 않습니다. 이제 문제는 Ctrl+ CASAP을 누르는 것입니다 (위의 예에서는 명령을 실행 한 직후에 눌렀습니다) . 필요하지 않은 모든 정보를 인쇄하는 데 여전히 시간이 걸립니다 .

내가 시도한 것

터미널을 마침내 잡을 때 재미있는 결과를 얻도록 Ctrl+를 C너무 세게 눌러 보았습니다 .

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

나는 또한에 대해 읽어 Ctrl+ S분명히 터미널 얘기하는 데 사용되는 "정지 출력을, 내가 잡을 필요" 하지만 분명히 그것은 아무것도하지 않는다.

기타 세부 사항

내가 실행하는 프로그램이 그런 식으로 끝날 수 있다는 것을 기억하지 못하더라도 어떤 상황에서도 스스로를 구출 할 수 있도록 내가 실행하는 명령을 변경하지 않고 싶습니다.

내 SSH 클라이언트는 CYGWIN_NT-6.1-WOW64 luna 1.7.30(0.272/5/3) 2014-05-23 10:36 i686 Cygwin터미널 유형이로 설정된 MinTTY의 Cygwin ( )에서 실행 됩니다 xterm-256color.

SSH 서버는 데비안 ( Linux burza 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686 i686 i686 GNU/Linux) 에서 실행됩니다 .


어떤 시스템에서 출력을 생성하는 실제 프로그램을 실행하고 있습니까? Linux, Unix 또는 Windows? 리눅스와 유닉스 Ctrl-O는 "이 터미널에 쓰여진 모든 출력을 버린다"는 것을 받아 들여야 한다.
Mark Plotnick

서버는 데비안에서 실행됩니다. 질문을 수정했습니다. Ctrl-O는 아무것도하지 않는 것 같습니다. 아마도 그것은 클라이언트 일입니까?
rr-

-j점프 스크롤을 활성화하기 위해 옵션으로 xterm을 시작할 수 있습니다 . 기본 문제는 원격에서 터미널 창에 표시 할 수있는 것보다 빠르게 데이터를 전송할 수 있다는 것입니다. 기본적으로 새 줄이 인쇄 될 때마다 창의 내용을 비트 블링해야합니다. 원격 시스템이 Ctrl-C를 수신 할 때까지 많은 양의 데이터가 버퍼링 될 수 있으며 터미널 프로그램이 모든 데이터를 표시하려고 시도합니다.
Mark Plotnick

그냥 아이디어 : 당신이 실수로 실행하는 정확한 명령이 있고 많은 출력을 생성하는 경우, 별칭을 추가하지 않는 이유는 .bashrc무엇입니까?
psimon

ssh 대신 mosh를 사용할 수 있습니다. mosh.mit.edu
gmatht

답변:


5

해당 출력 중 일부가 버퍼링됩니다. 실행중인 프로그램을 중단시키는 원격 끝으로 Ctrl+ C를 보냅니다 . 프로그램이 존재하고 쉘은 문자를 보내서 프롬프트를 다시 표시합니다. 프롬프트가 표시되기 전에 화면에 먼저 버퍼링 된 모든 데이터가 이미 표시되어 있습니다.

당신이 요구하는 것은 프로그램을 멈추고 전송중인 데이터가 어떻게 든 사라지는 것입니다. 그것은 이미 경로에 있기 때문에 일어날 수 없습니다.

이 데이터를 볼 수없는 유일한 방법은 터미널을 종료 한 다음 원격 장치에 다시 연결하는 것입니다. 그러나 버퍼링 된 데이터가 표시되기를 기다리는 것보다 훨씬 더 많은 노력이 필요합니다.


10

나는 보통 키 lessless사용하여 출력을 죽일 수 있도록 출력을 실행합니다 q.

$ cmd | less

$ cat /dev/urandom | less

   ss # 2

q+를 친 후에 Enter는 종료되고 일반 터미널로 돌아와서 깨끗하고 깨끗하게 유지됩니다.

왜 그런 일이 발생합니까?

발생한 문제는 디스플레이 출력과 함께 대기중인 버퍼 (STDOUT 용)가 있다는 것입니다. 이 버퍼는 너무 빨리 채워져 중지하기에 충분히 빨리 중단 할 수 없습니다.

                                    ss # 1

이 효과를 비활성화 / 제한하려면 STDOUT 버퍼링을 비활성화하여을 사용하여 반응 속도를 높일 수 stdbuf있지만 원하는 방식으로 설정하려면 이러한 설정을 사용해야합니다. STDOUT을 버퍼링 해제하려면 다음 명령을 사용할 수 있습니다.

$ stdbuf -o0 <cmd>

stdbuf귀하의 처분 옵션에 대한 자세한 내용은 맨 페이지를 참조하십시오 :

    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.

버퍼링 작동 방식에 대한 좋은 배경 지식을 얻으려면 표준 스트림의 버퍼링 이라는 제목의 Pixel Beat를 살펴 보는 것이 좋습니다 . 멋진 사진도 포함되어 있습니다.

참고 문헌


덧붙이 |less는 것을 기억하는 한 합리적 cmd입니다. 불행히도 나는 종종 그렇지 않습니다. 를 실행하는 cmd경우을 수신하기 전에 계산 결과 인쇄가 완료 될 때까지 기다려야합니다 ^C.
rr-

1
그것은 실제로 무슨 일이 일어나고 있는지 설명하지 않습니다. 결국 파이프가 없기 때문에 어떤 버퍼를 참조하고 있습니까?
Gilles 'SO- 악마 그만해'

@Gilles-죄송합니다. 버퍼는 화면의 버퍼입니다.
slm

어떤 버퍼? 커널에서? xterm에서?
Gilles 'SO- 악마 그만해'1

@Gilles-잠시만 기다려주십시오. 자세한 내용을 찾고 있습니다. 8-)
slm

3

몇 가지 레벨의 버퍼링이 있습니다. 누를 때Ctrl+C 프로그램이 터미널로 데이터를 방출하지 않습니다. 이것은 터미널 에뮬레이터가 아직 표시하지 않은 데이터에는 영향을 미치지 않습니다.

매우 빠른 속도로 데이터를 표시 할 때 터미널을 유지할 수없고 지연됩니다. 텍스트가 표시되는 것이이 난수를 생성하는 것보다 훨씬 비쌉니다. 예, 비트 맵 글꼴을 사용하더라도 암호화 품질의 난수를 생성하는 것은 비교가 훨씬 저렴합니다. (방금 내 컴퓨터에서 시도했고 X 프로세스가 CPU를 포화 시켰습니다 xterm. 몇 %를 차지하고 cat(난수 생성이 고려되는) 간신히 1 %에 도달했습니다. 그리고 비트 맵 글꼴이 있습니다.)

이 작업을 지금 중지하려면 터미널 에뮬레이터를 종료하십시오. 그렇게하지 않으려면 최소한 창을 최소화하십시오. xterm과 같은 지능형 터미널 에뮬레이터는 창을 매핑하지 않으므로 X CPU 시간이 절약되므로 가비지가 더 빨리 표시됩니다. X 서버는 우선 순위가 높으므로 xterm이 백그라운드에서 데이터를 처리하는 동안 시스템의 응답 속도에 큰 차이가 있습니다.

이 모든 것이 원격 쉘에서 진행될 때 생성 된 데이터 cat가 먼저 SSH 연결을 거쳐야 하기 때문에 지연이 더욱 심해 집니다. Ctrl+를 눌러도 CSSH 연결을 거쳐야합니다. 다소 높은 우선 순위를 갖지만 (대역 외부로 전송 됨) 더 많은 출력이 누적되는 데 여전히 시간이 걸립니다. SSH 연결을 닫는 과정에서 전송 중에 데이터를 억제하는 방법은 없습니다 ( Enter다음 을 눌러 수행 할 수 있음 ~.).


문제는 SSH와 관련이 있습니다. STDOUT 버퍼는 대화식 모드에서 사용해서는 안되지만 SSH는 대화식 모드를 올바르게 처리 할 수 ​​없습니다. 많은 출력이 트랜잭션에서 정지 될 수 있지만 Ctrl + C를받는 것은 SSH 프로세스이므로 Ctrl + C를 원격으로 전달할 수 없을 때 출력을 종료하는 것은 그의 책임입니다.
user4674453

응? Ctrl + C는 로컬 출력을 종료하지 않아야합니다. 그것은 전혀 일이 아닙니다. 원격 프로세스로 전달 될 수도 있고 원격 프로세스로 종료 될 수도 있습니다.
Gilles 'SO- 악마 그만'

"원격 프로세스를 중단시킬 수도 있고 중단하지 않을 수도있는 원격으로 전달되어야합니다." -그렇게하지 않아야합니다. Ctrl + C 중 하나를 발행하는 KILL 신호는 로컬 프로세스 전용입니다. 로컬 프로세스에 사용되지 않으면 "supposed to"라는 개념은 전혀 적용되지 않습니다.
user4674453

@ user4674453 아니요. Ctrl + C는 종료 신호가 아닙니다. 인터럽트 신호입니다. 역할은 대화식 프롬프트로 돌아가는 것입니다. 대화식 프롬프트가없는 프로그램 만 종료합니다.
Gilles 'SO- 악마 그만'

"인터럽트 신호입니다." 명령을 죽이는 인수이므로 킬 신호입니다. 원한다면 POSIX 신호라고도합니다. "그 역할은 대화식 프롬프트로 돌아가는 것입니다. 대화식 프롬프트가없는 프로그램 만 종료합니다." 바로 그거죠!!! 그리고 SSH는 예상대로 그렇게하지 않습니다.
user4674453

1

할 수있는 방법 찾을 충분해야한다 명령을 사용합니다. 다음 제안의 경우 두 번째 ssh 연결을 열어야 할 수도 있습니다.killcat

  • 드물게 CTRL+z보다 더 효과적 일 수 있습니다 CTRL+c더 빨리 대답 할 수 있습니다. 그 후에 명령을 일시 중단하면 kill %1작업 번호 와 함께 또는 작업 번호 와 상관없이 명령을 종료 할 수 있습니다 .
    이것은 여전히 ​​화면에서 아무것도 읽을 수 있기를 희망합니다 (홍수 임의 이진 텍스트는 문자 세트를 쉽게 망칠 수 있습니다). 창을 최소화하면 Gilles
    기억하는 것처럼 프로세스를 종료하는 것보다 시스템이 인터럽트 요청을 읽는 것이 더 빠를 것입니다. 따라서 일시 중단 / 중단, 최소화, 조금 기다렸다가 다시 최대화하면 해결책이 될 수 있습니다. 물론 ssh 연결을 통해 시간을 기다려야 할 것으로 기대합니다.

  • 다른 터미널 / 세션에서 pgrep cat(cat이 호출 된 명령 인 경우) 묻고 cat 프로세스가 더 많은 CPU를 사용하고 있는지 식별 할 수 있습니다. 다음을 통해보다 정확하게 식별 할 수 있습니다 pstree.

    pgrep 고양이 | awk '{print "pstree -sp"$ 1}'| 쉬 | grep sshd

    같은 출력으로 답변

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

    이 경우 cat PID 만 죽인 후 : kill 23131

노트 :

  • 보고 된 바와 같이 less 더 안전합니다.

1

나는 같은 문제가 있었고 여기에 대한 답변에 만족하지 않았으므로 더 깊이 파고 들었습니다. 다른 사람들은 이미 명령이 ssh보다 빠른 속도로 데이터를 출력한다고 언급 했으므로 데이터 버퍼와 버퍼를 중지 할 수 없습니다.

이 문제를 해결하려면 명령 출력을 ssh 세션이 취할 수있는 최대 속도로 조절하여 버퍼링을 피하기 위해 명령이 이미 존재합니다.

설정, 먼저 세션 최대 속도를 찾으십시오.

# 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

마지막으로 실제 명령을 적절하게 조절하십시오.

<YOUR_COMMAND> | pv -qL <RATE>

예:

/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

연결 속도가 때때로 약간 떨어질 경우 속도를 약간 낮추고 싶을 수 있습니다. 딥인 경우 동작이 응답하지 않는 ctrl-c로 돌아갑니다.

조절 가능한 고양이 별칭 (옵션) :

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

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

# usage: tcat <FILENAME>

이제 ctrl-c가 예상대로 작동하여 버퍼링이 거의 없기 때문에 즉시 출력을 종료합니다.


cat다른 소프트웨어와 달리 출력은 거의 문제가되지 않습니다. 저자는 단지 예로만 사용했습니다. 문제는 대개 다른 소프트웨어로 인한 것이므로 많은 양의 출력물을 생산할 수있을 경우 명확하지 않을 수 있습니다. 접두사 또는 접미사 명령을 입력하는 데 시간이 걸리므로 해결책이 없습니다. 결과에는 아무런 이득이 없습니다.
user4674453

0

Linux에는 정확하게 이것을 해결하는 소프트웨어가 있습니다 문제 있습니다 (다른 것들도 몇 가지). Windows의 터미널 에뮬레이터에서 Windows를 호출 할 수도 있습니다 (Windows를 사용하고있는 것 같습니다).

SSH 바이너리를 대체하는 mosh를 사용해보십시오 . SSH와 똑같이 작동합니다 ( mosh user@hostname대신 할 수 있으며 ssh user@hostname예상대로 정확하게 작동하고 개인 키 인증도 수행합니다).

기본적으로 패킷을 버퍼링하는 서버에서 별도의 프로세스를 실행합니다. 따라서 mosh에서 Ctrl + C를 누르면 원격 서버로 전달하여 추가 정보 전송을 중지합니다. 또한 키 입력 결과를 예측하여 키를 누를 때마다 몇 밀리 초가 절약됩니다.

단점 : 현재 mosh를 사용하는 동안 기록에서 위로 스크롤 할 수 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.