연결이 닫힐 때 "tail -f" 호출을 원격으로 종료하는 방법은 무엇입니까?

연결이 닫힐 때 "tail -f" 호출을 원격으로 종료하는 방법은 무엇입니까?

ssh user@remote_host tail -f /some/file방금 실행 하면 tail -f /some/file연결이 닫혀도 SSH 연결이 Remote_host에서 계속 실행된다는 것을 알았습니다 !

따라서 여러 번 연결하고 연결을 끊은 후에는 실행 횟수 tail -f /some/file가 늘어납니다. tail -fSSH 연결이 닫힐 때 실제로 종료하는 방법은 무엇입니까?

답변1

존재하다

ssh host tail -f file

클라이언트는 TCP 연결을 통해 서버 ssh에 연결됩니다 . sshd실행 시 표준 출력은 파이프로 리디렉션됩니다. 파이프의 다른 쪽 끝에서 콘텐츠를 읽고 sshd 프로토콜에 캡슐화하여 클라이언트에 보냅니다. (사용할 경우 stdout은 직접 소켓이 되지만 암호화가 추가되고 단일 TCP 연결(예: 포트/프록시/X11/터널 리디렉션, stderr)에서 여러 스트림을 다중화하는 기능이 추가되면 파이프를 사용해야 합니다.)hostsshdtail -fsshdsshrshdtailsshd

CTRL-C를 누르면 SIGINT가 ssh클라이언트로 전송됩니다. 그것은 ssh사망으로 이어질 수 있습니다. 연결이 끊어지면 TCP 연결이 닫힙니다. 따라서 On hostsshd죽습니다. tail종료되지는 않았지만 표준 출력은 이제 반대쪽 끝에 리더가 없는 파이프입니다. 따라서 다음 번에 stdout에 쓸 때 SIGPIPE를 수신하고 종료됩니다(최신 버전의 GNU tail모니터는 해당 stdout이 깨진 파이프가 된 것을 알아차리고 이 경우 즉시 종료됩니다.이 관련 질문에 대한 답변파손된 파이프를 감지하는 방법을 알아보세요.)

존재하다:

ssh -t host 'tail -f file'

와 사이의 통신이 파이프를 통하지 않고 sshd의사 tail터미널을 통해 이루어진다는 점을 제외하면 둘은 동일합니다. tailstdout은 슬레이브 의사 터미널(예: /dev/pts/12)이며 마스터에 대한 모든 쓰기 tail(tty 라인 규칙에 의해 수정될 수 있음)는 캡슐화되어 클라이언트로 전송됩니다.readsshdssh

클라이언트 측에서는 를 사용하여 -t터미널 sshraw모드로 전환합니다. 특히 이는 터미널 사양 모드와 터미널 신호 처리를 비활성화합니다.

따라서 키를 누르면 Ctrl+C클라이언트의 터미널 라인 규칙은 SIGINT를 작업에 보내지 않고 ssh대신 ^C연결을 통해 원격 터미널의 마스터 측으로 문자를 보내고 sshd씁니다 sshd. ^C원격 터미널의 회선 규칙은 SIGINT를 로 보냅니다 tail. 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

답변2

원격 측에 터미널을 할당해야 합니다.

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

심지어

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

관련 정보