지금 SSH 세션에서 실행되는 프로그램의 출력 중지 것 터미널을 마침내 잡을

문제

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) 에서 실행됩니다 .



답변

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

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

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


답변

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

$ cmd | less

$ cat /dev/urandom | less

   

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

왜 그런 일이 발생합니까?

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

                                    

이 효과를 비활성화 / 제한하려면 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를 살펴 보는 것이 좋습니다 . 멋진 사진도 포함되어 있습니다.

참고 문헌


답변

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

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

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

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


답변

할 수있는 방법 찾을 충분해야한다 명령을 사용합니다.
다음 제안의 경우 두 번째 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 더 안전합니다.

답변

나는 같은 문제가 있었고 여기에 대한 답변에 만족하지 않았으므로 더 깊이 파고 들었습니다. 다른 사람들은 이미 명령이 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가 예상대로 작동하여 버퍼링이 거의 없기 때문에 즉시 출력을 종료합니다.


답변

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

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

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

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