연결이 닫힐 때 "tail -f"라고하는 원격 종료 방법


24

난 그냥 실행하면 것을 발견 ssh user@remote_host tail -f /some/file, 다음 tail -f /some/fileREMOTE_HOST SSH 연결이 종료 된 경우에도 실행 계속!

따라서 몇 번의 연결 및 연결 해제 후 실행 수가 tail -f /some/file증가합니다. tail -fssh 연결이 닫힐 때 실제로 종료하는 방법 은 무엇입니까?

답변:


33

에서

ssh host tail -f file

ssh클라이언트가 연결 sshd에서 서버 host의 TCP 연결을 통해. stdout이 파이프로 리디렉션 된 상태로 sshd실행됩니다 tail -f. sshd파이프의 다른 쪽 끝에서 오는 내용을 읽고 sshd 프로토콜로 캡슐화하여 ssh클라이언트 로 보냅니다 . (와 함께 rshd, tailstdout은 소켓 이었지만, sshd암호화를 추가하고 단일 TCP 연결에서 여러 스트림 (예 : 포트 / 에이전트 / X11 / 터널 리디렉션, stderr)을 멀티플렉싱 할 수 있으므로 파이프를 사용해야합니다).

CTRL-C를 누르면 SIGINT가 ssh클라이언트 로 전송됩니다 . 그로 인해 ssh사망하게됩니다. 죽으면 TCP 연결이 닫힙니다. 그러므로 on hostsshd죽습니다. tail죽지 않았지만 stdout은 이제 반대쪽 끝에 독자가없는 파이프입니다. 따라서 다음에 stdout에 무언가를 쓸 때 SIGPIPE를 받고 죽습니다.

에서:

ssh -t host 'tail -f file'

대신 파이프와 인의 간의 통신한다는 것을 제외하고는 동일한 것이다 sshdtail의사 단말로한다. tail의 표준 출력하는 슬레이브 의사 단말 (등 /dev/pts/12)과 어떤 tail가 작성 read하여 마스터 측 (아마도 TTY 광고 분야 의해 변형)에 sshd상기 캡슐화 보냈 ssh클라이언트.

클라이언트 측에서로 -t, ssh풋 터미널이있는 raw모드입니다. 특히, 이는 터미널 표준 모드 및 터미널 신호 처리를 비활성화합니다.

누를 때, Ctrl+C클라이언트의 터미널 제어 규칙이에 SIGINT를 보내는 대신 ssh작업, 그것은 바로 전송 ^C받는 연결을 통해 캐릭터 sshdsshd그 쓰기 ^C원격 터미널의 마스터 측에 있습니다. 원격 단말기의 제어 규칙은을 전송 SIGINTtail. tail그런 다음 sshd연결이 끊어지고 연결을 종료하고 닫은 후 ssh종료됩니다 (포트 포워딩 또는 기타로 바쁘지 않은 경우).

또한,과 -t의 경우 ssh클라이언트 다이가 (예를 들어 사용자가 입력 한 경우 ~.), 연결이 닫히고 sshd다이. 결과적으로 SIGHUP이 (으)로 전송됩니다 tail.

자, 사용하면 -t부작용이 있다는 것을 명심하십시오 . 예를 들어, 기본 터미널 설정 을 사용하면 원격 시스템에 따라 \n문자가 변환 \r\n되고 더 많은 일이 발생할 수 있으므로 stty -opost해당 출력이 의도되지 않은 경우 원격 호스트에서 (출력 사후 처리 사용 안함) 을 발행 할 수 있습니다 터미널 :

$ ssh  localhost 'echo x' | hd
00000000  78 0a                                             |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000  78 0d 0a                                          |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000  78 0a                                             |x.|
00000002

-t/ 를 사용하는 또 다른 단점은 -ttstdout과 stderr이 클라이언트에서 구별되지 않는다는 것입니다. 원격 명령의 stdout 및 stderr은 모두 ssh클라이언트의 stdout에 기록됩니다 .

$ ssh localhost ls /x  | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1

자세한 설명을 주셔서 대단히 감사합니다! 두 가지 답변을받을 수 있기를 바랍니다 ..
Dmitry Frank

"로 -t, ssh클라이언트가 사망하는 경우 (예 :을 입력 한 경우 ~.)" ~.다시 무엇입니까 ?
x-yuri

1
@ x-yuri ~.는 클라이언트 연결을 끊기 위해 입력 한 이스케이프 시퀀스입니다. 자세한 내용 man ssh을 참조하십시오.
Stéphane Chazelas

11

원격 측에서 터미널 할당이 필요합니다.

ssh -t user@remote_host tail -f /some/file

또는

ssh -tt user@remote_host tail -f /some/file

1
둘 다 -t또는 감사 -tt합니다. 그러나 나는 여전히 이것의 실제 이유를 이해할 수 없습니다. 즉, 셸을 원격으로 호출하고 연결을 닫으면 셸이 종료됩니다. 그러나 tail -f그렇지 않습니다. 물론 -t에서 옵션에 대해 이미 읽었 man ssh지만별로 도움이되지 않았습니다. 일부 제네릭을 이해하지 못하는 것 같습니다. 문서에 대해 읽거나 직접 설명 할 문서를 제안하면 기쁠 것입니다. 감사!
Dmitry Frank

2
@DmitryFrank 내 이해는 이것입니다 : 연결이 끊어지면을 sshd보냅니다 SIGHUP. 그러나 터미널이없는 곳에서는 터미널 연결 끊기가 없습니다 ...
Hauke ​​Laging

고마워, 나는 SIGHUP다른 신호를 읽을 것입니다.
Dmitry Frank

참고 : 난 그냥 실행하려고 tail -f, 그때 나는 연 htop및 전송 SIGHUP(눌러서에 F9-> 1-> Enter), 그리고 tail -f종료! 따라서 이유는 약간 달라야합니다.
Dmitry Frank

3
@DmitryFrank 문제를 잘못 이해했습니다. 문제는 되지tail반응하지 것이다 SIGHUP. 문제는 의사 터미널없이 SIGHUP** 전송되지 않는다 ' tail입니다. 두 경우 모두 에 연결 strace하면 알 수 있습니다 tail.
Hauke ​​Laging
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.